Gmail Calendar Documents Reader Web more »
Recently Visited Groups | Help | Sign in
Google Groups Home
ruby and list comprehension
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  17 messages - Expand all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Brad Tilley  
View profile  
 More options Nov 25 2006, 6:47 pm
Newsgroups: comp.lang.ruby
From: Brad Tilley <rtil...@vt.edu>
Date: Sun, 26 Nov 2006 08:47:26 +0900
Local: Sat, Nov 25 2006 6:47 pm
Subject: ruby and list comprehension
In Python, I can do this to arrays:

added = [x for x in new_data if x not in old_data]
removed = [x for x in old_data if x not in new_data]
same = [x for x in new_data if x in old_data]

I believe this is known as list comprehension in Python. How is this done in
Ruby?

Thanks,
Brad


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Timothy Hunter  
View profile  
 More options Nov 25 2006, 6:53 pm
Newsgroups: comp.lang.ruby
From: Timothy Hunter <TimHun...@nc.rr.com>
Date: Sun, 26 Nov 2006 08:53:00 +0900
Subject: Re: ruby and list comprehension
Brad Tilley wrote:
> In Python, I can do this to arrays:

> added = [x for x in new_data if x not in old_data]
> removed = [x for x in old_data if x not in new_data]
> same = [x for x in new_data if x in old_data]

> I believe this is known as list comprehension in Python. How is this done in
> Ruby?

> Thanks,
> Brad

This question comes up from time to time. You can search the archives of
comp.lang.ruby on Google Groups for "list comprehension" to find the
previous threads on this topic.

http://groups.google.com/group/comp.lang.ruby/search?group=comp.lang....


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Louis J Scoras  
View profile  
 More options Nov 25 2006, 7:06 pm
Newsgroups: comp.lang.ruby
From: "Louis J Scoras" <louis.j.sco...@gmail.com>
Date: Sun, 26 Nov 2006 09:06:43 +0900
Local: Sat, Nov 25 2006 7:06 pm
Subject: Re: ruby and list comprehension
On 11/25/06, Brad Tilley <rtil...@vt.edu> wrote:

> In Python, I can do this to arrays:

> added = [x for x in new_data if x not in old_data]
> removed = [x for x in old_data if x not in new_data]
> same = [x for x in new_data if x in old_data]

Short answer:

    added   = new_data.reject {|i| old_data.include? i }
    removed = old_data.reject {|i| new_data.include? i }
    same    = new_data.select {|i| old_data.include? i }

Provided ordering isn't important here, you can do the same thing with
set operations.

    require 'set'

    old_data = old_data.to_set
    new_data = new_data.to_set

    added   = new_data - old_data
    removed = old_data - new_data
    same    = new_data.intersection(old_data)

Note those returns sets, not arrays.

--
Lou.


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Mike Austin  
View profile  
 More options Nov 25 2006, 7:19 pm
Newsgroups: comp.lang.ruby
From: Mike Austin <no...@nowhere.com>
Date: Sun, 26 Nov 2006 00:19:38 GMT
Local: Sat, Nov 25 2006 7:19 pm
Subject: Re: ruby and list comprehension

Brad Tilley wrote:
> In Python, I can do this to arrays:

> added = [x for x in new_data if x not in old_data]
> removed = [x for x in old_data if x not in new_data]
> same = [x for x in new_data if x in old_data]

> I believe this is known as list comprehension in Python. How is this done in
> Ruby?

> Thanks,
> Brad

Because Ruby's select() returns a value, not just a boolean like in Smalltalk,
you can do the following:

[1,2,3].select { |x| ![2,3,4].include? x }
[2,3,4].select { |x| ![1,2,3].include? x }
[1,2,3].select { |x| [2,3,4].include? x }

You can also use Array operators:

[1,2,3] - [2,3,4]
[2,3,4] - [1,2,3]
[1,2,3] & [2,3,4]

Mike


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Brad Tilley  
View profile  
 More options Nov 25 2006, 7:29 pm
Newsgroups: comp.lang.ruby
From: Brad Tilley <rtil...@vt.edu>
Date: Sun, 26 Nov 2006 09:29:37 +0900
Local: Sat, Nov 25 2006 7:29 pm
Subject: Re: ruby and list comprehension
Quoting Mike Austin <no...@nowhere.com>:

> Because Ruby's select() returns a value, not just a boolean like in
> Smalltalk,
> you can do the following:

> [1,2,3].select { |x| ![2,3,4].include? x }
> [2,3,4].select { |x| ![1,2,3].include? x }
> [1,2,3].select { |x| [2,3,4].include? x }

> You can also use Array operators:

> [1,2,3] - [2,3,4]
> [2,3,4] - [1,2,3]
> [1,2,3] & [2,3,4]

Thanks for all the examples guys! That's great stuff.

    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
James Cunningham  
View profile  
 More options Nov 26 2006, 5:42 pm
Newsgroups: comp.lang.ruby
From: James Cunningham <jameshcunning...@gmail.com>
Date: Sun, 26 Nov 2006 17:42:09 -0500
Local: Sun, Nov 26 2006 5:42 pm
Subject: Re: ruby and list comprehension
On 2006-11-25 18:47:26 -0500, Brad Tilley <rtil...@vt.edu> said:

> In Python, I can do this to arrays:

> added = [x for x in new_data if x not in old_data]
> removed = [x for x in old_data if x not in new_data]
> same = [x for x in new_data if x in old_data]

> I believe this is known as list comprehension in Python. How is this done in
> Ruby?

> Thanks,
> Brad

I found this while web searching for the same thing recently; I can't
recall where I found it. It's a cute little hack.

class Array
  def comprehend
    return self unless block_given?
    result = []
    self.each { |i| result.push yield(i) }
    result.compact
  end
end

Then:

added = new_data.comprehend { |x| x if not old_data.include? x }
removed = old_data.comprehend { |x| x if not new_data.include? x }
same = new_data.comprehend { |x| x if old_data.include? x }

Best,
James


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
dbl...@wobblini.net  
View profile  
 More options Nov 26 2006, 5:52 pm
Newsgroups: comp.lang.ruby
From: dbl...@wobblini.net
Date: Mon, 27 Nov 2006 07:52:37 +0900
Local: Sun, Nov 26 2006 5:52 pm
Subject: Re: ruby and list comprehension
Hi --

I'm not getting how that's better than:

   added = new_data.select {|x| not old_data.include?(x) }

(or the reject equivalent) and so on.

David

--
                   David A. Black | dbl...@wobblini.net
Author of "Ruby for Rails"   [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog)        [2] | Co-director, Ruby Central, Inc.   [4]
[1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com    | [4] http://www.rubycentral.org


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
James Cunningham  
View profile  
 More options Nov 26 2006, 7:01 pm
Newsgroups: comp.lang.ruby
From: James Cunningham <jameshcunning...@gmail.com>
Date: Sun, 26 Nov 2006 19:01:53 -0500
Local: Sun, Nov 26 2006 7:01 pm
Subject: Re: ruby and list comprehension
On 2006-11-26 17:52:37 -0500, dbl...@wobblini.net said:

I should have clarified. In your example there's no difference, but the
above gives a general replacement for list comprehensions.

irb(main):018:0> (1..25).to_a.comprehend { |x| x**2 if not x % 2 == 0 }
=> [1, 9, 25, 49, 81, 121, 169, 225, 289, 361, 441, 529, 625]

Best,
James


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
James Cunningham  
View profile  
 More options Nov 26 2006, 7:03 pm
Newsgroups: comp.lang.ruby
From: James Cunningham <jameshcunning...@gmail.com>
Date: Sun, 26 Nov 2006 19:03:34 -0500
Local: Sun, Nov 26 2006 7:03 pm
Subject: Re: ruby and list comprehension
On 2006-11-26 19:01:53 -0500, James Cunningham
<jameshcunning...@gmail.com> said:

Er, "your" meaning "Brad Tilley's".

Best,
James


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Martin DeMello  
View profile  
 More options Nov 27 2006, 3:09 am
Newsgroups: comp.lang.ruby
From: "Martin DeMello" <martindeme...@gmail.com>
Date: Mon, 27 Nov 2006 17:09:26 +0900
Local: Mon, Nov 27 2006 3:09 am
Subject: Re: ruby and list comprehension
On 11/27/06, James Cunningham <jameshcunning...@gmail.com> wrote:

> added = new_data.comprehend { |x| x if not old_data.include? x }
> removed = old_data.comprehend { |x| x if not new_data.include? x }
> same = new_data.comprehend { |x| x if old_data.include? x }

I wrote http://zem.novylen.net/ruby/fproduct.rb a while ago to emulate
list comprehensions in ruby - for example:

for x,y,z in product 1..40,
                       1..40, proc {|x,y| x <= y},
                       1..40, proc {|x,y,z| x**2 + y**2 == z**2}
    p [x,y,z]
end

The benefit is that the filters do get applied in order (sorted on
arity), so that it doesn't generate all the combinations first and
then filter.

martin


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Robert Klemme  
View profile  
 More options Nov 27 2006, 3:30 am
Newsgroups: comp.lang.ruby
From: Robert Klemme <shortcut...@googlemail.com>
Date: Mon, 27 Nov 2006 09:30:58 +0100
Local: Mon, Nov 27 2006 3:30 am
Subject: Re: ruby and list comprehension
On 27.11.2006 01:01, James Cunningham wrote:

> On 2006-11-26 17:52:37 -0500, dbl...@wobblini.net said:
>> I'm not getting how that's better than:

>>    added = new_data.select {|x| not old_data.include?(x) }

>> (or the reject equivalent) and so on.
> I should have clarified. In your example there's no difference, but the
> above gives a general replacement for list comprehensions.

> irb(main):018:0> (1..25).to_a.comprehend { |x| x**2 if not x % 2 == 0 }
> => [1, 9, 25, 49, 81, 121, 169, 225, 289, 361, 441, 529, 625]

Frankly, I am not sure I find this better than using the built in methods:

irb(main):001:0> (1..25).inject([]) {|a,x| a << x**2 unless x % 2 == 0; a}
=> [1, 9, 25, 49, 81, 121, 169, 225, 289, 361, 441, 529, 625]

irb(main):002:0> (1..25).inject([]) {|a,x| a << x**2 if x % 2 == 1; a}
=> [1, 9, 25, 49, 81, 121, 169, 225, 289, 361, 441, 529, 625]

irb(main):003:0> (1..25).select {|x| x % 2 == 1}.map! {|x| x**2}
=> [1, 9, 25, 49, 81, 121, 169, 225, 289, 361, 441, 529, 625]

Kind regards

        robert


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
piggybox  
View profile  
 More options Nov 27 2006, 4:49 am
Newsgroups: comp.lang.ruby
From: "piggybox" <Sky....@gmail.com>
Date: 27 Nov 2006 01:49:12 -0800
Local: Mon, Nov 27 2006 4:49 am
Subject: Re: ruby and list comprehension
I've always thought list comprehension is just a bunch of
map/filter/... transformation until I saw the following version of
permutation:

in Haskell:
permutation [] = [[]]
permutation xs = [x:ys | x <- xs, ys <- permutation (delete x xs)]

in Erlang:
permutation([]) -> [[]];
permutation(L)  -> [[H|T] || H <- L, T <- permutation(L--[H])].

really neat, isn't it?


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
James Cunningham  
View profile  
 More options Nov 27 2006, 7:59 am
Newsgroups: comp.lang.ruby
From: James Cunningham <jameshcunning...@gmail.com>
Date: Mon, 27 Nov 2006 07:59:17 -0500
Local: Mon, Nov 27 2006 7:59 am
Subject: Re: ruby and list comprehension
On 2006-11-27 03:30:58 -0500, Robert Klemme <shortcut...@googlemail.com> said:

That's fair enough, but I think list comprehension is clearer than
method chaining and one-liner array accumulation. I'm afraid

a << x**2 if x % 2 == 1; a

is perhaps just a little less elegant than

x**2 if x % 2 == 1

I think the nicest thing about Ruby, though, is that it's even possible.

Best,
James


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Devin Mullins  
View profile  
 More options Nov 27 2006, 9:21 am
Newsgroups: comp.lang.ruby
From: Devin Mullins <twif...@comcast.net>
Date: Mon, 27 Nov 2006 23:21:52 +0900
Local: Mon, Nov 27 2006 9:21 am
Subject: Re: ruby and list comprehension
piggybox wrote:
> in Haskell:
> permutation [] = [[]]
> permutation xs = [x:ys | x <- xs, ys <- permutation (delete x xs)]

> in Erlang:
> permutation([]) -> [[]];
> permutation(L)  -> [[H|T] || H <- L, T <- permutation(L--[H])].

> really neat, isn't it?

Yes. :)

    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Phrogz  
View profile  
 More options Nov 27 2006, 11:39 pm
Newsgroups: comp.lang.ruby
From: "Phrogz" <ga...@refinery.com>
Date: 27 Nov 2006 20:39:57 -0800
Local: Mon, Nov 27 2006 11:39 pm
Subject: Re: ruby and list comprehension

James Cunningham wrote:
> I found this while web searching for the same thing recently; I can't
> recall where I found it. It's a cute little hack.

> class Array
>   def comprehend
>     return self unless block_given?
>     result = []
>     self.each { |i| result.push yield(i) }
>     result.compact
>   end
> end

Maybe I don't comprehend comprehending, but why the result/each instead
of map?

class Array
  def comprehend
    if block_given?
      map{ |i| yield( i ) }.compact
    else
      self
    end
  end
end

or perhaps better

class Array
  def comprehend( &block )
    block ? map( &block ).compact : self
  end
end


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
James Cunningham  
View profile  
 More options Nov 28 2006, 12:13 am
Newsgroups: comp.lang.ruby
From: James Cunningham <jameshcunning...@gmail.com>
Date: Tue, 28 Nov 2006 00:13:05 -0500
Local: Tues, Nov 28 2006 12:13 am
Subject: Re: ruby and list comprehension
On 2006-11-27 23:39:57 -0500, "Phrogz" <ga...@refinery.com> said:

> class Array
>   def comprehend( &block )
>     block ? map( &block ).compact : self
>   end
> end

The same.

You're just cleverer than I am. ;)

Best,
James


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Robert Klemme  
View profile  
 More options Nov 28 2006, 5:30 am
Newsgroups: comp.lang.ruby
From: Robert Klemme <shortcut...@googlemail.com>
Date: Tue, 28 Nov 2006 11:30:21 +0100
Local: Tues, Nov 28 2006 5:30 am
Subject: Re: ruby and list comprehension
On 28.11.2006 05:39, Phrogz wrote:

> class Array
>   def comprehend( &block )
>     block ? map( &block ).compact : self
>   end
> end

This could go into Enumerable instead.  There is no special Array
functionality involved.

Kind regards

        robert


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2009 Google