2

Is there a straightforward way to do something like the following without excessive looping?

myArray = [["a","b"],["c","d"],["e","f"]]
if myArray.includes?("c")
   ...

I know this works fine if it's just a normal array of chars... but I would like something equally as elegant for an array of an array of chars (bonus points for helping convert this to an array of tuples).

3
  • 1
    What do you mean by "key"? Do you just want to check if the item exists in any of the sub-arrays, or are you treating the sub-arrays as key-value pairs and so want to check if the item exists in the first position in any of the sub-arrays? Commented May 19, 2016 at 22:42
  • I cannot recommend this, but if, as in the example, all elements of myArray are of the same size, you could write, require 'array'; m = Matrix[*myArray]; m.index("f") #=> [2,1]; m.index("g") #=> nil, [2,1] being truthy. Commented May 22, 2016 at 16:24
  • In case you're just coming to Ruby from another language, one Ruby convention is to use snake-case for names of variables and methods, so myArray would generally be written my_array. Snake-case is lower-case letters and underscores, and in the case of method names, the last character can be "?" or "!". You don't have to adopt that convention, but 99%+ of Rubiests do. Commented May 22, 2016 at 16:32

5 Answers 5

7

If you only need a true/false answer you can flatten the array and call include on that:

>> myArray.flatten.include?("c")
=> true
Sign up to request clarification or add additional context in comments.

2 Comments

...or myArray.flatten.index("c").
@CarySwoveland, good point! For those interested, the difference is that index returns the position of "c" in the array (or nil if "c" isn't found), whereas include? only returns true or false.
5

You can use assoc:

my_array = [['a', 'b'], ['c', 'd'], ['e', 'f']]

if my_array.assoc('c')
  # ...

It actually returns the whole subarray:

my_array.assoc('c') #=> ["c", "d"]

or nil if there is no match:

my_array.assoc('g') #=> nil

There's also rassoc to search for the second element:

my_array.rassoc('d') #=> ["c", "d"]

1 Comment

I was curious why we have those two methods. For those interested, this SO question and blog entry shed some light on that.
3
my_array  = [["a","b"],["c","d"],["e","f"]]
p my_hash = my_array.to_h # => {"a"=>"b", "c"=>"d", "e"=>"f"}
p my_hash.key?("c") #  => true

Comments

1

You can use Array#any?

myArray = [["a","b"],["c","d"],["e","f"]]
if myArray.any? { |x| x.includes?("c") }
  # some code here

Comments

1

The find_index method works well for this:

myArray = [["a","b"],["c","d"],["e","f"]]
puts "found!" if myArray.find_index {|a| a[0] == "c" }

The return value is the array index of the pair or nil if the pair is not found.

You can capture the pair's value (or nil if not found) this way:

myArray.find_index {|a| a[0] == "c" } || [nil, nil])[1]
# => "d"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.