Using grep on subarrays - help!

Can anyone help with this? I thought grep would find any element that
matches in an array. It seems not...

irb(main):028:0> test = [['one', 'vol1'], ['one', 'vol2'], ['two',
'vol3']]
=> [["one", "vol1"], ["one", "vol2"], ["two", "vol3"]]
irb(main):029:0> test.grep(/one/)
=> []
irb(main):030:0> test.each.grep(/one/)
=> []
irb(main):031:0> test
=> [["one", "vol1"], ["one", "vol2"], ["two", "vol3"]]
irb(main):032:0> test.grep('one')
=> []
irb(main):033:0> test2 = ['one', 'one', 'two', 'three']
=> ["one", "one", "two", "three"]
irb(main):034:0> test2.grep(/one/)
=> ["one", "one"]
irb(main):035:0>

···

--
Posted via http://www.ruby-forum.com/.

test.each {|x| puts x.grep /one/}

=> one
one

If you want to choose all pairs that match:

result =
test.each {|x| result << x unless x.grep(/one/).empty?}
result

=> [["one", "vol1"],["one","vol2"]]

Jesus.

···

On Sun, Apr 3, 2011 at 3:32 PM, Simon Harrison <simon@simonharrison.net> wrote:

Can anyone help with this? I thought grep would find any element that
matches in an array. It seems not...

irb(main):028:0> test = [['one', 'vol1'], ['one', 'vol2'], ['two',
'vol3']]
=> [["one", "vol1"], ["one", "vol2"], ["two", "vol3"]]
irb(main):029:0> test.grep(/one/)
=>

Thanks again Jesus. Is it just me or does that seem a bit longwinded.
Any idea why one can't just directly an array with subarrays?

···

--
Posted via http://www.ruby-forum.com/.

Simon Harrison wrote in post #990675:

Can anyone help with this? I thought grep would find any element that
matches in an array. It seems not...

You are trying to use grep() to match strings, yet your test array does
not contain strings--it contains sub-arrays. So first you have to grab
the sub-arrays, and then you can apply grep to the sub-arrays because
they contain strings.

···

--
Posted via http://www.ruby-forum.com/\.

Thanks for all the tips. I think #select fits best:

file_results = @films.select { |a, b| /#{@film}/i =~ a }

Just one question. Obviously in the above, a and b refer to the first
and second elements in each subarray. Let's say we have this array:

=> [["one", "two", "three"], ["one"], ["two", "three"], ["one",
"three"]]

What would be the best way to search for 'one' (or whatever) in this
case?

Cheers

···

--
Posted via http://www.ruby-forum.com/.

Thanks Rob,very useful. Any chance of expanding on this at all:

"a quick, single block
arg" (as in arry.map{|_|_.something} to mean the same as
arry.map(&:something) without needing Symbol#to_proc)."

···

--
Posted via http://www.ruby-forum.com/.

More to-the-point:

test.reject { |x| x.grep(/one/).empty? }

···

2011/4/3 Jesús Gabriel y Galán <jgabrielygalan@gmail.com>

result =
test.each {|x| result << x unless x.grep(/one/).empty?}
result

7stud -- wrote in post #990727:

new_arr = test.select do |arr|
  if arr.include?(target)
    true
  end
end

I guess that can be written more succinctly as:

new_arr = test.select do |arr|
  arr.include?(target)
end

···

--
Posted via http://www.ruby-forum.com/\.

Thanks for all the tips. I think #select fits best:

file_results = @films.select { |a, b| /#{@film}/i =~ a }

Just one question. Obviously in the above, a and b refer to the first
and second elements in each subarray. Let's say we have this array:

=> [["one", "two", "three"], ["one"], ["two", "three"], ["one",
"three"]]

What would be the best way to search for 'one' (or whatever) in this
case?

Cheers

-- Posted via http://www.ruby-forum.com/\.

@films = [["one", "two", "three"], ["one"], ["two", "three"],

["one", "three"]]
=> [["one", "two", "three"], ["one"], ["two", "three"], ["one", "three"]]

@film = 'One'

=> "One"

@films.select{|film,*_| /#{@film}/i =~ film}

=> [["one", "two", "three"], ["one"], ["one", "three"]]

_ is a valid identifier and I tend to use it to mean either "a throwaway placeholder" (like in this usage) or "a quick, single block arg" (as in arry.map{|_|_.something} to mean the same as arry.map(&:something) without needing Symbol#to_proc).

-Rob

Rob Biedenharn
Rob@AgileConsultingLLC.com http://AgileConsultingLLC.com/
rab@GaslightSoftware.com http://GaslightSoftware.com/

···

On Apr 4, 2011, at 3:06 PM, Simon Harrison wrote:

Here's a little example from an error handler in a script (first occurrence in an open buffer):

   rescue => e
     if $stderr.isatty
       $stderr.puts e.message
       $stderr.puts e.backtrace.select {|_| %r{/app/} =~ _}.join("\n\t")
     else
       raise
     end
   end

While I could replace the "_" with a name like "line" or "backtrace_line", that doesn't really increase the expressiveness when the entire block is one statement/expression.

-Rob

Rob Biedenharn
Rob@AgileConsultingLLC.com http://AgileConsultingLLC.com/
rab@GaslightSoftware.com http://GaslightSoftware.com/

···

On Apr 4, 2011, at 4:05 PM, Simon Harrison wrote:

Thanks Rob,very useful. Any chance of expanding on this at all:

"a quick, single block
arg" (as in arry.map{|_|_.something} to mean the same as
arry.map(&:something) without needing Symbol#to_proc)."

-- Posted via http://www.ruby-forum.com/\.

Simon Harrison wrote in post #990886:

Thanks for all the tips. I think #select fits best:

file_results = @films.select { |a, b| /#{@film}/i =~ a }

Just one question. Obviously in the above, a and b refer to the first
and second elements in each subarray. Let's say we have this array:

=> [["one", "two", "three"], ["one"], ["two", "three"], ["one",
"three"]]

Neither grep() or include?() depended on the size of the sub-arrays they
are searching, so the answer is the same:

data = [
  ["one", "two", "three"],
  ["one"],
  ["two", "three"],
  ["one","three"]
]

target = 'one'

results = data.select do |arr|
  arr.include?(target)
end

p results

--output:--
[["one", "two", "three"], ["one"], ["one", "three"]]

However, if your target will only appear in the first position of the
array, then it is much more efficient to just check the first element of
each array:

data = [
  ["one", "two", "three"],
  ["ONE"],
  ["two", "three"],
  ["oNe","three"]
]

target = 'one'

results = data.select do |arr|
  arr[0].downcase == target
end

p results

--output:--
[["one", "two", "three"], ["ONE"], ["oNe", "three"]]

···

--
Posted via http://www.ruby-forum.com/\.

It seems we may want to match at the first position only, so I'd
rather do one of those

irb(main):003:0> test.select {|a,b| /one/ =~ a}
=> [["one", "vol1"], ["one", "vol2"]]
irb(main):004:0> test.select {|a,b| a == "one"}
=> [["one", "vol1"], ["one", "vol2"]]

If we are only interested in the other bit

irb(main):005:0> test.select {|a,b| a == "one"}.map {|a,b| b}
=> ["vol1", "vol2"]

Or, with #inject for a change since we know the key when doing exact matches

irb(main):006:0> test.inject() {|r,(a,b)| a == "one" ? r << b : r}
=> ["vol1", "vol2"]

Kind regards

robert

···

On Sun, Apr 3, 2011 at 4:44 PM, Adam Prescott <adam@aprescott.com> wrote:

2011/4/3 Jesús Gabriel y Galán <jgabrielygalan@gmail.com>

result =
test.each {|x| result << x unless x.grep(/one/).empty?}
result

More to-the-point:

test.reject { |x| x.grep(/one/).empty? }

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/