2010-07-13 6 views
43

puedo generar unas pocas líneas de código que va a hacer esto, pero me pregunto si hay una manera agradable Rubyesque limpia de hacer esto. En caso de que no he sido claro, lo que estoy buscando es un método de matriz que devolverá true si se les da (por ejemplo) o [3,3,3,3,3]["rabbits","rabbits","rabbits"] pero volverá falsa con [1,2,3,4,5] o ["rabbits","rabbits","hares"].¿Cómo compruebo si todos los elementos de una matriz son idénticos?

Gracias

Respuesta

54
class Array 
    def same_values? 
    self.uniq.length == 1 
    end 
end 


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

Qué tal este? Sin embargo, devuelve falso para una matriz vacía, puede cambiarlo a < = 1 y se devolverá verdadero en ese caso. Dependiendo de lo que necesites

+2

Eso es muy elegante. Puedo usar el .uniq.length == 1 directamente en mi código en lugar de la forma en que lo ha hecho (solo lo estoy usando una vez, así que lo mantengo SECO). Sería bueno si hubiera un built.same_values? método. No necesito preocuparme por el caso de la matriz vacía en mi código, ya que a) no debería aparecer en mi situación yb) si lo hiciera, me gustaría que devuelva falso. Gracias. – brad

+2

Tenga en cuenta que 'uniq' utiliza' hash' y 'eql?' Y no '==' que pueden ser o no lo que usted quiere. –

+1

Se podría, por supuesto, extender esto a las matrices anidadas con == 1 self.flatten.uniq.lenth –

67

Puede utilizar Enumerable#all? que devuelve verdadero si el bloque dado devuelve verdadero para todos los elementos de la colección.

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

(Si la matriz está vacía, el bloque está nunca llamó, al hacerlo array[0] es seguro.)

+0

¿Qué '(array.any {| x | x = array [0]!}?)'!? No iterará a través de todos los elementos después de la primera aparición de un valor diferente. –

+4

@ Nu-hin Ninguno '¿todos?'. – sepp2k

+0

Sí, mi mal, gracias. –

9

I respuesta preferido también como la mejor, corto y dulce. Si todos los elementos eran de la misma clase Enumerable, tal como numérico o de cadena, se podría utilizar

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

Slick. Muy resbaladizo – brad

+2

Los objetos no tienen que estar en la misma clase, que sólo necesitan ser capaces de implementar '' <=> (el operador de la nave espacial). –

+0

@AndrewGrimm El operador de nave espacial hace que este código falle si los objetos son de tipos diferentes. –

1

Solía ​​usar:

def add_equal?(arr) arr.reduce { |x,y| x == y ? x : nil } end 

puede fallar cuando arr contiene nil.

1

yo usaría:

array = ["rabbits","rabbits","hares", nil, nil] 
array.uniq.compact.length == 1 
Cuestiones relacionadas