I have the following hash:

``hash = {"1"=>[ 5, 13, "B", 4, 10],"2"=>[27, 19, "B", 18, 20],"3"=>[45, 41, "B", 44, 31],"4"=>[48, 51, "B", 58, 52],"5"=>[70, 69, "B", 74, 73]}``

Here is my code:

`` if hash.values.all? { |array| array[0] == "B" } ||hash.values.all? { |array| array[1] == "B" } ||hash.values.all? { |array| array[2] == "B" } ||hash.values.all? { |array| array[3] == "B" } ||hash.values.all? { |array| array[4] == "B" }puts "Hello World"``

What my code does is iterates through an array such that if the same element appears in the same index position of each array, it will output the string "Hello World" (Since "B" is in the [2] position of each array, it will puts the string. Is there a way to condense my current code without having a bunch of or's connecting each index of the array?

Assuming all arrays are always of the same length, the following gives you the column indexes where all values are equal:

``````hash.values.transpose.each_with_index.map do |column, index|
index if column.all? {|x| x == column[0] }
end.compact
``````

The result is `[2]` for your `hash`. So you know that for all arrays the index 2 has the same values. You can print `"Hello World"` if the resulting array has at least one element.

How does it work?

`hash.values.transpose` gives you all the arrays, but with transposed (all rows are now columns) values:

``````hash.values.transpose
=> [[5, 27, 45, 48, 70],
[13, 19, 41, 51, 69],
["B", "B", "B", "B", "B"],
[4, 18, 44, 58, 74],
[10, 20, 31, 52, 73]]
``````

`.each_with_index.map` goes over every row of the transposed array while providing an inner array and its index. We look at every inner array, yielding the column index only if all elements are equal using `all?`.

``````hash.values.transpose.each_with_index.map {|column, index| index if column.all? {|x| x == column[0] }
=> [nil, nil, 2, nil, nil]
``````

Finally, we `compact` the result to get rid of the `nil` values.

Edit: First, I used `reduce` to find the column with identical elements. @Nimir pointed out, that I re-implemented `all?`. So I edited my anwer to use `all?`.

From @tessi brilliant answer i though of this way:

``````hash.values.transpose.each_with_index do |column, index|
puts "Index:#{index} Repeated value:#{column.first}" if column.all? {|x| x == column[0]}
end
#> Index:2 Repeated value:B
``````

### How?

Well, the `transpose` already solves the problem:

``````hash.values.transpose
=> [[5, 27, 45, 48, 70],
[13, 19, 41, 51, 69],
["B", "B", "B", "B", "B"],
[4, 18, 44, 58, 74],
[10, 20, 31, 52, 73]
]
``````

We can do:

``````column.all? {|x| x == column[0]}
``````

To find column with identical items

Assuming that all the values of the hash will be arrays of the same size, how about something like:

``````hash
=> {"1"=>[5, 13, "B", 4, 10], "2"=>[27, 19, "B", 18, 20], "3"=>[45, 41, "B", 44, 31], "4"=>[48, 51, "B", 58, 52], "5"=>[70, 69, "B", 74, 73]}

arr_of_arrs = hash.values
=> [[5, 13, "B", 4, 10], [27, 19, "B", 18, 20], [45, 41, "B", 44, 31], [48, 51, "B", 58, 52], [70, 69, "B", 74, 73]]

first_array = arr_of_arrs.shift
=> [5, 13, "B", 4, 10]

first_array.each_with_index do |element, index|
arr_of_arrs.map {|arr| arr[index] == element }.all?
end.any?
=> true
``````

This is not really different from what you have now, as far as performance - in fact, it may be a bit slower. However, it allows for a dynamic number of incoming key/value pairs.

I ended up using the following:

``````fivebs = ["B","B","B","B","B"]

if hash.values.transpose.any? {|array| array == fivebs}
puts "Hello World"
``````

If efficiency, rather than readability, is most important, I expect this decidedly un-Ruby-like and uninteresting solution probably would do well:

``````arr = hash.values
arr.first.size.times.any? { |i| arr.all? { |e| e[i] == ?B } }
#=> true
``````

Only one intermediate array (`arr`) is constructed (e.g, no transposed array), and it quits if and when a match is found.

More Ruby-like is the solution I mentioned in a comment on your question:

``````hash.values.transpose.any? { |arr| arr.all? { |e| e == ?B } }
``````

As you asked for an explanation of @Phrogz's solution to the earlier question, which is similar to this one, let me explain the above line of code, by stepping through it:

``````a = hash.values
#=> [[ 5, 13, "B",  4, 10],
#    [27, 19, "B", 18, 20],
#    [45, 41, "B", 44, 31],
#    [48, 51, "B", 58, 52],
#    [70, 69, "B", 74, 73]]

b = a.transpose
#=> [[  5,  27,  45,  48,  70],
#    [ 13,  19,  41,  51,  69],
#    ["B", "B", "B", "B", "B"],
#    [  4,  18,  44,  58,  74],
#    [ 10,  20,  31,  52,  73]]
``````

In the last step:

``````b.any? { |arr| arr.all? { |e| e == ?B } }
#=> true
``````

(where `?B` is shorthand for the one-character string "B") an enumerator is created:

``````c = b.to_enum(:any?)
#=> #<Enumerator: [[  5,  27,  45,  48,  70],
#                  [ 13,  19,  41,  51,  69],
#                  ["B", "B", "B", "B", "B"],
#                  [  4,  18,  44,  58,  74],
#                  [ 10,  20,  31,  52,  73]]:any?>
``````

When the enumerator (any enumerator) is acting on an array, the elements of the enumerator are passed into the block (and assigned to the block variable, here `arr`) by Array#each. The first element passed into the block is:

``````arr = [5, 27, 45, 48, 70]
``````

and the following is executed:

``````arr.all? { |e| e == ?B }
#=> [5, 27, 45, 48, 70].all? { |e| e == ?B }
#=> false
``````

Notice that `false` is returned to `each` right after:

``````5 == ?B
#=> false
``````

is evaluated. Since `false` is returned, we move on to the second element of the enumerator:

``````[13, 19, 41, 51, 69].all? { |e| e == ?B }
#=> false
``````

so we continue. But

``````["B", "B", "B", "B", "B"].all? { |e| e == ?B }
#=> true
``````

so when `true` is returned to `each`, the latter returns `true` and we are finished.

Top