tags:

views:

123

answers:

3

I can generate a few lines of code that will do this but I'm wondering if there's a nice clean Rubyesque way of doing this. In case I haven't been clear, what I'm looking for is an array method that will return true if given (say) [3,3,3,3,3] or ["rabbits","rabbits","rabbits"] but will return false with [1,2,3,4,5] or ["rabbits","rabbits","hares"].

Thanks

+11  A: 

You can use Enumerable#all? which returns true if the given block returns true for all the elements in the collection.

array.all? {|x| x == array[0]}

(If the array is empty, the block is never called, so doing array[0] is safe.)

sepp2k
+6  A: 
class Array
  def same_values?
    self.uniq.length == 1
  end
end


[1, 1, 1, 1].same_values?
[1, 2, 3, 4].same_values?

What about this one? It returns false for an empty array though, you can change it to <= 1 and it will return true in that case. Depending on what you need.

Francisco Soto
That's pretty elegant. I can just use the .uniq.length == 1 directly in my code rather than the way you've done it (I'm only using it once so I'm keeping it DRY). It'd be nice if there was a built in .same_values? method. I don't need to worry about the empty array case in my code as a) it shouldn't come up in my situation and b) if it did I would want it to return false.Thanks.
brad
Note that `uniq` uses `hash` and `eql?` and not `==` which may or may not be what you want.
Jörg W Mittag
One could of course extend this to nested arrays with self.flatten.uniq.lenth == 1
Cary Swoveland
+1  A: 

I too like preferred answer best, short and sweet. If all elements were from the same Enumerable class, such as Numeric or String, one could use

def all_equal?(array) array.max == array.min end

Cary Swoveland
Slick. Very slick.
brad