# Checking to see if all values in an array are equal

I have an array that might be either one-dimensional, two-dimension, or three-dimensional. I'm wanting to check to see if all values in a given direction are constant.

Here are 3 functions:

# Check to see if all values in the first dimension are equal
def constant1D(arr)
arr.inject(true) { |same, val| same and val == arr[0] }
end

# Check to see if all values in the second dimension are equal
def constant2Dy(arr)
arr.inject(true) { |same, x| same and constant1D(x) }
end

# Check to see if all values in the third dimension are equal
def constant3Dz(arr)
arr.inject(true) { |same, x| same and constant2Dy(x) }
end


And here is the code that would be checking:

constantX = constant1D(values)
constantY = ((mapType == :twoD) and constant2Dy(values))
constantZ = ((mapType == :threeD) and constant3Dz(values))


Here are some sample runs:

threeDa = [[[1, 2, 3], [4, 5, 6], [7, 8, 9]], [[1, 2, 3], [4, 5, 6], [7, 8, 9]], [[1, 2, 3], [4, 5, 6], [7, 8, 9]]]
threeDb = [[[1, 2, 3], [1, 2, 3], [1, 2, 3]], [[4, 5, 6], [4, 5, 6], [4, 5, 6]], [[7, 8, 9], [7, 8, 9], [7, 8, 9]]]
threeDc = [[[1, 1, 1], [2, 2, 2], [3, 3, 3]], [[4, 4, 4], [5, 5, 5], [6, 6, 6]], [[7, 7, 7], [8, 8, 8], [9, 9, 9]]]
>> constant1D(threeDa)
=> true
>> constant1D(threeDb)
=> false
>> constant1D(threeDc)
=> false
>> constant2Dy(threeDa)
=> false
>> constant2Dy(threeDb)
=> true
>> constant2Dy(threeDc)
=> false
>> constant3Dz(threeDa)
=> false
>> constant3Dz(threeDb)
=> false
>> constant3Dz(threeDc)
=> true


Is this the most "Ruby" way, or is there a better way? E.g., referencing arr[0] in the above has a little bit of code smell to me, but perhaps I'm overthinking it.

[Rewritten]

You want to avoid inject, as uniq.size is O(n) and clearer. Monkey patching array makes the code clearer and is idiomatic Ruby. Methods that return a boolean should end in ?. Method names should be snake_case. Here you go:

class Array
# Check to see if all values in the first dimension are equal
def constant_1d?
uniq.size == 1
end

# Check to see if all values in the second dimension are equal
def constant_2dy?
all?(&:constant_1d?)
end

# Check to see if all values in the third dimension are equal
def constant_3dz?
all?(&:constant_2dy?)
end
end

• O(N) complexity, good. Sep 11 '15 at 17:50
• I've verified that this works fine (with == 1 instead of .one?) as a replacement for constant1D, but does the inject seem bad for the other 2D and 3D checks? For constant2Dy, I've verified that I can do arr.transpose.uniq.size == 1, but am still pondering constant3Dz. Sep 11 '15 at 18:01
• @Ben Hocking, what do you think? Sep 12 '15 at 15:56
• each is used to perform side-effects, it returns the array being iterated, I don't see how this can be working. Sep 12 '15 at 19:42
• @dankohn, tested it out with my arrays and it works fine. It's always nice to try thinking in different ways. Thanks! Sep 14 '15 at 11:36