search multi dimensional arrays

my_array = [ 5, 3, 4, [ "abc", 3, 5 ], [ "x", 5 ] ]

i want to search for "x" do you have to loop thru the array to search this item

or is there some easier way to do this.

i would like to delete x from the array to achieve this.

my_array_deleted = [ 5, 3, 4, [ "abc", 3, 5 ] ]

thanks

Do you really want to remove any sub-array in which “x” occurs?

my_array_deleted = [ 5, 3, 4, [ “abc”, 3, 5 ] ]

Or, do you want to remove only any elements that equal “x”?

my_array_deleted = [ 5, 3, 4, [ “abc”, 3, 5 ], [ 5 ] ]

I just want to be sure that you really want to also remove the 5 that’s in the same sub-array as “x” in your example.

Regards,

Craig

opps your right, i want to delete the sub-array so the 5 would be deleted as well. gosh, your reading my mind.

Hi --

it works. can you explain *a

thanks

it works.

can you explain *a

My very basic understanding of the splat operator (*) on an array is that it expands the array. Here’s an example IRB session.

a = [1,2,3]

=> [1, 2, 3]

puts *a

1

2

3

=> nil

David knows Ruby very, very well. Perhaps he’ll expand on my very simple explanation.

Regards,

Craig

David A. Black wrote:

   my_array.delete_if {|a| [*a].include?("x") }    => [5, 3, 4, ["abc", 3, 5]]

The splat here really isn't necessary.

The * unpacks an array. It is often used with argument to methods:

  def foo(a, b, c)     puts "a:#{a} b:#{b} c:#{c}"   end

  my_array = [1,2,3]   foo(*my_array) #=> "a:1 b:2 c:3"

So the splat lets you pass an array as individual arguments. Or it can work the other way around.

  def foo(*args)     puts "arguments: #{args.size}"   end

  foo(1,2,3) #=> 3

This example allows individual arguments to be passed in as an array. This pattern is used a lot throughout rails.

In David's example:

  my_array.delete_if {|a| [*a].include?("x") }

The "a" in that code will be each subarray of this main array. *a will unpack that array into individual elements. And the wrapped around *a will make a new array containing those elements.

This all means that:

  a = [1,2,3]   a == [*a] #=> true

So, the simpler way to do this is just:

  my_array.delete_if {|a| a.include?("x") }

Hopefully that explains the splat a bit.

Hi --

David A. Black wrote:

   my_array.delete_if {|a| [*a].include?("x") }    => [5, 3, 4, ["abc", 3, 5]]

The splat here really isn't necessary.

Yes it is (see below).

In David's example:

my_array.delete_if {|a| [*a].include?("x") }

The "a" in that code will be each subarray of this main array. *a will unpack that array into individual elements. And the wrapped around *a will make a new array containing those elements.

This all means that:

a = [1,2,3] a == [*a] #=> true

So, the simpler way to do this is just:

my_array.delete_if {|a| a.include?("x") }

Except the array my_array doesn't consist only of subarrays; it also contains some scalar elements. Doing it your way, you'd end up calling (for example) 5.include?.

That's why I un-arrayed and re-arrayed each element.

David

David A. Black wrote:

thanks, for the excellent explanation.