¿Quieres una matriz real, o simplemente algo similar a una matriz?
Kathy Van Stone el
1
No hay seguridad de tipografía en Ruby. No se preocupe si su variable es una matriz o no. El método debe suponer que es así y seguir adelante y llamar a contar con él:
my_array.count
Por favor, lea las respuestas de zgchurch y DigitalRoss para un Ruby más idiomático.
La verificación de tipos es para Java. Siga adelante y solo llame al conteo en la variable. Escriba pruebas unitarias para asegurarse de que el método funcione como se esperaba.
user132447
14
@ user132447 en realidad, java es de tipo seguro, por lo que no debe preocuparse por verificar ningún tipo
grinch
8
Lo rechacé ahora porque no creo que sea una buena práctica en un lenguaje como Ruby. La respuesta de @zgchurch es claramente un enfoque mucho más idiomático a la pregunta. En casos como este, creo que tiene mucho más sentido intentar averiguar qué significa el OP, en lugar de darle una escopeta a ciegas ...
Per Lundberg
1
¿Por qué querrías usar kind_of?()sobre otras soluciones? Alguna explicación sobre los beneficios de su respuesta sobre otros sería útil para futuros lectores.
AlbertEngelB
148
¿Estás seguro de que debe ser una matriz? Es posible que pueda usarlo respond_to?(method)para que su código funcione para cosas similares que no son necesariamente matrices (tal vez alguna otra cosa numerable). Si realmente necesita un array, entonces la publicación que describe el Array#kind\_of?método es la mejor.
En este caso, estoy seguro de que será una matriz. Pero es bueno saber este método también. +1
BuddyJoe el
Idea interesante, estoy usando push / pop en una estructura de datos. ¿Algo más que las matrices respondería a esos métodos?
Dibujó
3
Si desea algo más parecido a una matriz, es posible que desee respond_to?(:to_ary).
Andrew Grimm
21
En general, esta es una buena práctica para el desarrollo de OO. Leí donde alguien dijo básicamente: no te imagines que estás llamando métodos a tus objetos. Les estás enviando mensajes. Si un objeto sabe cómo responder a su mensaje, no le importa de qué clase es, o si tiene un método llamado eso, o si está creando dinámicamente una respuesta a través de method_missing. Lo importante es, ¿puede responder a su mensaje? Esto permite una mejor abstracción de la función y la implementación. Puede cambiar el objeto que usa más adelante, siempre que siga respondiendo correctamente.
Nathan Long
2
El único problema con esto es decir que quiero verificar si algo es un iterable indexado, por lo que las matrices, las listas vinculadas, etc. serían geniales, pero ¿no quiero almacenes de valores clave como hashes?
Colton Voege
58
En lugar de probar un Array,solo convertir lo que obtienes en un nivel, Array,por lo que tu código solo necesita manejar un caso.
t =[*something]# or...
t =Array(something)# or...def f *x
...end
Ruby tiene varias formas de armonizar una API que puede tomar un objeto o una matriz de objetos, por lo tanto, adivina por qué quieres saber si algo es una matriz, tengo una sugerencia.
El operador splat contiene mucha magia que puede buscar, o simplemente puede llamar Array(something)para agregar un contenedor de matriz si es necesario. Es similar a [*something]en este caso.
def f x
p Array(x).inspect
p [*x].inspect
end
f 1# => "[1]"
f [1]# => "[1]"
f [1,2]# => "[1, 2]"
O bien, puede usar el símbolo splat en la declaración de parámetros y .flatten, luego , darle un tipo diferente de recopilador. (Para el caso, también puede llamar .flattenarriba).
def f *x
p x.flatten.inspect
end# => nil
f 1# => "[1]"
f 1,2# => "[1, 2]"
f [1]# => "[1]"
f [1,2]# => "[1, 2]"
f [1,2],3,4# => "[1, 2, 3, 4]"
Y, gracias gregschlom , a veces es más rápido simplemente usarlo Array(x)porque cuando ya es un Arrayno necesita crear un nuevo objeto.
¿Qué agrega esto a las respuestas que han estado en el sitio durante casi siete años ...?
Martin Tournoij
66
@Carpetsmoker no hay una respuesta concisa que haga referencia is_a?en todo este hilo. Lo más cercano es a [1,2,3].is_a? Enumerable. Todavía creo que vale la pena tener esta respuesta.
dipole_moment
44
Sabes ... en realidad tienes razón ... Podría haber jurado que vi eso allí antes: - / ¡Haz un voto!
Martin Tournoij
16
Parece que buscas algo que tiene algún concepto de elementos. Por lo tanto, recomiendo ver si es así Enumerable. Eso también garantiza la existencia de#count .
Por ejemplo,
[1,2,3].is_a?Enumerable[1,2,3].count
en cuenta que, si bien size, lengthy counttodo el trabajo para las matrices, countes el significado aquí - (por ejemplo, 'abc'.lengthy 'abc'.sizetanto trabajo, pero 'abc'.countno funciona de esa manera).
Precaución: una cadena es_a? Enumerable, entonces quizás esto no sea lo que quieres ... depende de tu concepto de una matriz como objeto.
Use Array () en lugar de la verificación explícita de Array o [* var], cuando trate con una variable que desea tratar como Array, pero no está seguro de que sea una matriz.
# bad
paths =[paths]unless paths.is_a?Array
paths.each {|path| do_something(path)}# bad (always creates a new Array instance)[*paths].each {|path| do_something(path)}# good (and a bit more readable)Array(paths).each {|path| do_something(path)}
Esto producirá resultados inesperados al pasar un hash porque to_ase invoca en cada argumento agregado a la nueva matriz, por lo que Array({id: 100})regresa[[:id, 100]]
Respuestas:
Probablemente quieras usar
kind_of()
.fuente
is_a?
yinstance_of?
. Ver stackoverflow.com/questions/3893278/…kind_of?()
sobre otras soluciones? Alguna explicación sobre los beneficios de su respuesta sobre otros sería útil para futuros lectores.¿Estás seguro de que debe ser una matriz? Es posible que pueda usarlo
respond_to?(method)
para que su código funcione para cosas similares que no son necesariamente matrices (tal vez alguna otra cosa numerable). Si realmente necesita unarray
, entonces la publicación que describe elArray#kind\_of?
método es la mejor.fuente
respond_to?(:to_ary)
.En lugar de probar un
Array,
solo convertir lo que obtienes en un nivel,Array,
por lo que tu código solo necesita manejar un caso.Ruby tiene varias formas de armonizar una API que puede tomar un objeto o una matriz de objetos, por lo tanto, adivina por qué quieres saber si algo es una matriz, tengo una sugerencia.
El operador splat contiene mucha magia que puede buscar, o simplemente puede llamar
Array(something)
para agregar un contenedor de matriz si es necesario. Es similar a[*something]
en este caso.O bien, puede usar el símbolo splat en la declaración de parámetros y
.flatten
, luego , darle un tipo diferente de recopilador. (Para el caso, también puede llamar.flatten
arriba).Y, gracias gregschlom , a veces es más rápido simplemente usarlo
Array(x)
porque cuando ya es unArray
no necesita crear un nuevo objeto.fuente
[*nil] => []
. Entonces podrías terminar con una matriz vacía.Array(foo)
es mucho más eficiente que[*foo]
[1,2,3].is_a? Array
se evalúa como verdaderofuente
is_a?
en todo este hilo. Lo más cercano es a[1,2,3].is_a? Enumerable
. Todavía creo que vale la pena tener esta respuesta.Parece que buscas algo que tiene algún concepto de elementos. Por lo tanto, recomiendo ver si es así
Enumerable
. Eso también garantiza la existencia de#count
.Por ejemplo,
en cuenta que, si bien
size
,length
ycount
todo el trabajo para las matrices,count
es el significado aquí - (por ejemplo,'abc'.length
y'abc'.size
tanto trabajo, pero'abc'.count
no funciona de esa manera).Precaución: una cadena es_a? Enumerable, entonces quizás esto no sea lo que quieres ... depende de tu concepto de una matriz como objeto.
fuente
Tratar:
EDITAR : La otra respuesta es mucho mejor que la mía.
fuente
También considere usar
Array()
. De la Guía de estilo de comunidad de Ruby :fuente
to_a
se invoca en cada argumento agregado a la nueva matriz, por lo queArray({id: 100})
regresa[[:id, 100]]