Ruby-test para array


¿Cuál es el camino correcto para:

is_array("something") # => false         (or 1)

is_array(["something", "else"]) # => true  (or > 1)

O para obtener el recuento de elementos en él?

 230
Author: BuddyJoe, 2009-10-07

7 answers

Probablemente quieras usar kind_of?().

>> s = "something"
=> "something"
>> s.kind_of?(Array)
=> false
>> s = ["something", "else"]
=> ["something", "else"]
>> s.kind_of?(Array)
=> true
 458
Author: ry.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-04 21:20:57

¿Estás seguro de que necesita para ser una matriz? Es posible que pueda usar respond_to?(method) para que su código funcione para cosas similares que no son necesariamente matrices (tal vez alguna otra cosa enumerable). Si realmente necesita un array, entonces el post que describe el método Array#kind\_of? es el mejor.

['hello'].respond_to?('each')
 140
Author: zgchurch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-04 21:21:24

En lugar de probar un Array, simplemente convierta lo que obtenga en un Array, de un solo nivel para que su código solo necesite manejar el único 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 que, adivinando por qué desea saber si algo es una matriz, tengo una sugerencia.

El operador splat contiene mucha magia puede buscar, o simplemente puede llamar a Array(something) que agregará un Envoltura 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 splat en la declaración de parámetros y luego .flatten, dándole un tipo diferente de recopilador. (Para el caso, usted podría llamar .flatten arriba, también.)

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 usar Array(x) porque cuando ya es un Array no necesita crear un nuevo objeto.

 53
Author: DigitalRoss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:30

Parece que buscas algo que tiene algún concepto de elementos. Por lo tanto, recomiendo ver si es Enumerable. Eso también garantiza la existencia de #count.

Por ejemplo,

[1,2,3].is_a? Enumerable
[1,2,3].count

Tenga en cuenta que, mientras size, length y count todo funciona para matrices, count es el significado correcto aquí - (por ejemplo, 'abc'.length y 'abc'.size ambos funcionan, pero 'abc'.count no funciona así).

Precaución: una cadena is_a? Enumerable, así que quizás esto no es lo que quieres... depende de su concepto de una matriz como objeto.

 12
Author: Peter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-07 00:12:49

[1,2,3].is_a? Array se evalúa como verdadero.

 12
Author: dipole_moment,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-16 15:05:20

Intenta:

def is_array(a)
    a.class == Array
end

EDITAR: La otra respuesta es mucho mejor que la mía.

 8
Author: Lucas Jones,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-06 20:24:48

También considere usar Array(). De la Guía de Estilo de la Comunidad de Ruby :

Use Array() en lugar de explicit Array check o [*var], al tratar con una variable que desea tratar como una matriz, pero no está seguro es 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) }
 5
Author: GuyPaddock,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-12 20:38:04