[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Using array.select with grep

Milo Thurston

8/1/2008 12:45:00 PM

Using irb I set up the following arrays:

>> arr1
=> ["one", "two", "three"]
>> arr2
=> ["two", "three", "four"]

I would expect to be able to collect the elements of arr1 that are also
in arr2 using select and grep, i.e.

>> arr1.select { |y| arr2.grep(y) }
=> ["two", "three"]

But what I actually get is:

>> arr1.select { |y| arr2.grep(y) }
=> ["one", "two", "three"]

What is my error or misunderstanding here?

Before anyone asks, I'm not using the array intersecttion (arr1 & arr2)
because I am testing this expression prior to using it to find objects
in an array (arr1) where an object parameter is found in an array of
strings (arr2), e.g. to find all people from the array of people objects
whose first name is in a list of names:

arr1.select { |y| arr2.grep(y.string_of_interest) }

Although if there's a better way of doing that I'd be interested to
know.
--
Posted via http://www.ruby-....

15 Answers

Stefano Crocco

8/1/2008 12:51:00 PM

0

On Friday 01 August 2008, Milo Thurston wrote:
> Using irb I set up the following arrays:
> >> arr1
>
> => ["one", "two", "three"]
>
> >> arr2
>
> => ["two", "three", "four"]
>
> I would expect to be able to collect the elements of arr1 that are also
> in arr2 using select and grep, i.e.
>
> >> arr1.select { |y| arr2.grep(y) }
>
> => ["two", "three"]
>
> But what I actually get is:
> >> arr1.select { |y| arr2.grep(y) }
>
> => ["one", "two", "three"]
>
> What is my error or misunderstanding here?
>
> Before anyone asks, I'm not using the array intersecttion (arr1 & arr2)
> because I am testing this expression prior to using it to find objects
> in an array (arr1) where an object parameter is found in an array of
> strings (arr2), e.g. to find all people from the array of people objects
> whose first name is in a list of names:
>
> arr1.select { |y| arr2.grep(y.string_of_interest) }
>
> Although if there's a better way of doing that I'd be interested to
> know.

Array#grep returns an array with the matches, which means it returns an empty
array, which evaluates to true, if there's no match. You can do what you want
with

arr1.select{|y| !arr2.grep(y).empty?}

I hope this helps

Stefano

Milo Thurston

8/1/2008 12:54:00 PM

0

Stefano Crocco wrote:
> arr1.select{|y| !arr2.grep(y).empty?}
>
> I hope this helps


Yes, that does the job nicely. Thanks!
--
Posted via http://www.ruby-....

Stefan Lang

8/1/2008 12:57:00 PM

0

2008/8/1 Milo Thurston <knirirr@gmail.com>:
> Using irb I set up the following arrays:
>
>>> arr1
> => ["one", "two", "three"]
>>> arr2
> => ["two", "three", "four"]
>
> I would expect to be able to collect the elements of arr1 that are also
> in arr2 using select and grep, i.e.
>
>>> arr1.select { |y| arr2.grep(y) }
> => ["two", "three"]
>
> But what I actually get is:
>
>>> arr1.select { |y| arr2.grep(y) }
> => ["one", "two", "three"]
>
> What is my error or misunderstanding here?

Because grep returns an empty array when it can't find the
given string. And an empty array (everything except false and nil,
actually) is true in Ruby. Use #include? instead:

arr1.select { |y| arr2.include?(y) }

Stefan

David A. Black

8/1/2008 1:01:00 PM

0

Hi --

On Fri, 1 Aug 2008, Stefan Lang wrote:

> 2008/8/1 Milo Thurston <knirirr@gmail.com>:
>> Using irb I set up the following arrays:
>>
>>>> arr1
>> => ["one", "two", "three"]
>>>> arr2
>> => ["two", "three", "four"]
>>
>> I would expect to be able to collect the elements of arr1 that are also
>> in arr2 using select and grep, i.e.
>>
>>>> arr1.select { |y| arr2.grep(y) }
>> => ["two", "three"]
>>
>> But what I actually get is:
>>
>>>> arr1.select { |y| arr2.grep(y) }
>> => ["one", "two", "three"]
>>
>> What is my error or misunderstanding here?
>
> Because grep returns an empty array when it can't find the
> given string. And an empty array (everything except false and nil,
> actually) is true in Ruby. Use #include? instead:
>
> arr1.select { |y| arr2.include?(y) }

No, that's not the same.

>> array = %w{ one two three }
=> ["one", "two", "three"]
>> array.grep(/e/)
=> ["one", "three"]
>> array.include?("e")
=> false


David

--
Rails training from David A. Black and Ruby Power and Light:
* Advancing With Rails August 18-21 Edison, NJ
* Co-taught by D.A. Black and Erik Kastner
See http://www.r... for details and updates!

Shadowfirebird

8/1/2008 1:01:00 PM

0

Someone please correct me if I'm barking up the wrong tree, but the
block in select wants a function that returns a logical, and grep
isn't one.

It seems to work if you use include?(), instead, though.

irb(main):004:0> a1 = [ "one", "two", "three" ]
=> ["one", "two", "three"]
irb(main):005:0> a2 = ["two", "three", "four" ]
=> ["two", "three", "four"]
irb(main):006:0> a1.find_all{|x| a2.grep(x)}
=> ["one", "two", "three"]
irb(main):007:0> a1.find_all{|x| a2.grep(x) == true}
=> []
irb(main):007:0> a1.find_all{|x| a2.include?(x)}
=> ["two", "three"]



On 8/1/08, Milo Thurston <knirirr@gmail.com> wrote:
> Using irb I set up the following arrays:
>
>>> arr1
> => ["one", "two", "three"]
>>> arr2
> => ["two", "three", "four"]
>
> I would expect to be able to collect the elements of arr1 that are also
> in arr2 using select and grep, i.e.
>
>>> arr1.select { |y| arr2.grep(y) }
> => ["two", "three"]
>
> But what I actually get is:
>
>>> arr1.select { |y| arr2.grep(y) }
> => ["one", "two", "three"]
>
> What is my error or misunderstanding here?
>
> Before anyone asks, I'm not using the array intersecttion (arr1 & arr2)
> because I am testing this expression prior to using it to find objects
> in an array (arr1) where an object parameter is found in an array of
> strings (arr2), e.g. to find all people from the array of people objects
> whose first name is in a list of names:
>
> arr1.select { |y| arr2.grep(y.string_of_interest) }
>
> Although if there's a better way of doing that I'd be interested to
> know.
> --
> Posted via http://www.ruby-....
>
>


--
Me, I imagine places that I have never seen / The colored lights in
fountains, blue and green / And I imagine places that I will never go
/ Behind these clouds that hang here dark and low
But it's there when I'm holding you / There when I'm sleeping too /
There when there's nothing left of me / Hanging out behind the
burned-out factories / Out of reach but leading me / Into the
beautiful sea

Robert Klemme

8/1/2008 1:15:00 PM

0

2008/8/1 Milo Thurston <knirirr@gmail.com>:

> Before anyone asks, I'm not using the array intersecttion (arr1 & arr2)
> because I am testing this expression prior to using it to find objects
> in an array (arr1) where an object parameter is found in an array of
> strings (arr2), e.g. to find all people from the array of people objects
> whose first name is in a list of names:
>
> arr1.select { |y| arr2.grep(y.string_of_interest) }
>
> Although if there's a better way of doing that I'd be interested to
> know.

Just one additional remark: if your Arrays grow large you might
benefit from converting them to Set which has faster lookups.

Kind regards

robert


--
use.inject do |as, often| as.you_can - without end

David A. Black

8/1/2008 1:17:00 PM

0

Hi --

On Fri, 1 Aug 2008, shadowfirebird@gmail.com wrote:

> Someone please correct me if I'm barking up the wrong tree, but the
> block in select wants a function that returns a logical, and grep
> isn't one.
>
> It seems to work if you use include?(), instead, though.
>
> irb(main):004:0> a1 = [ "one", "two", "three" ]
> => ["one", "two", "three"]
> irb(main):005:0> a2 = ["two", "three", "four" ]
> => ["two", "three", "four"]
> irb(main):006:0> a1.find_all{|x| a2.grep(x)}
> => ["one", "two", "three"]
> irb(main):007:0> a1.find_all{|x| a2.grep(x) == true}
> => []
> irb(main):007:0> a1.find_all{|x| a2.include?(x)}
> => ["two", "three"]

See my previous post. #grep and #include? are not the same.


David

--
Rails training from David A. Black and Ruby Power and Light:
* Advancing With Rails August 18-21 Edison, NJ
* Co-taught by D.A. Black and Erik Kastner
See http://www.r... for details and updates!

Sebastian Hungerecker

8/1/2008 1:20:00 PM

0

David A. Black wrote:
> No, that's not the same.
>
> >> array = %w{ one two three }
>
> => ["one", "two", "three"]
>
> >> array.grep(/e/)
>
> => ["one", "three"]

array.grep("e")
=> []

So since the code in question only deals with strings and not regexen, using
include? does indeed have the same result as checking whether grep returned
an empty array.

HTH,
Sebastian
--
Jabber: sepp2k@jabber.org
ICQ: 205544826

Stefano Crocco

8/1/2008 1:28:00 PM

0

On Friday 01 August 2008, shadowfirebird@gmail.com wrote:
> Someone please correct me if I'm barking up the wrong tree, but the
> block in select wants a function that returns a logical, and grep
> isn't one.

Everything in ruby can be used as a boolean value, so technically you can use
it. The only problem is that the value grep returns is always a 'true' value.

Stefano

Stefan Lang

8/1/2008 1:37:00 PM

0

2008/8/1 David A. Black <dblack@rubypal.com>:
> Hi --
>
> On Fri, 1 Aug 2008, Stefan Lang wrote:
>
>> 2008/8/1 Milo Thurston <knirirr@gmail.com>:
>>>
>>> Using irb I set up the following arrays:
>>>
>>>>> arr1
>>>
>>> => ["one", "two", "three"]
>>>>>
>>>>> arr2
>>>
>>> => ["two", "three", "four"]
>>>
>>> I would expect to be able to collect the elements of arr1 that are also
>>> in arr2 using select and grep, i.e.
>>>
>>>>> arr1.select { |y| arr2.grep(y) }
>>>
>>> => ["two", "three"]
>>>
>>> But what I actually get is:
>>>
>>>>> arr1.select { |y| arr2.grep(y) }
>>>
>>> => ["one", "two", "three"]
>>>
>>> What is my error or misunderstanding here?
>>
>> Because grep returns an empty array when it can't find the
>> given string. And an empty array (everything except false and nil,
>> actually) is true in Ruby. Use #include? instead:
>>
>> arr1.select { |y| arr2.include?(y) }
>
> No, that's not the same.

>>> array = %w{ one two three }
>
> => ["one", "two", "three"]
>>>
>>> array.grep(/e/)
>
> => ["one", "three"]
>>>
>>> array.include?("e")
>
> => false

Given Milo's use case, he's only using strings, so it doesn't
matter. include? is clearer in this case, IMO.

Stefan