Qual è il modo giusto per:
is_array("something") # => false (or 1)
is_array(["something", "else"]) # => true (or > 1)
o per ottenere il conteggio degli elementi in esso?
Qual è il modo giusto per:
is_array("something") # => false (or 1)
is_array(["something", "else"]) # => true (or > 1)
o per ottenere il conteggio degli elementi in esso?
Risposte:
Probabilmente vuoi usare kind_of()
.
>> s = "something"
=> "something"
>> s.kind_of?(Array)
=> false
>> s = ["something", "else"]
=> ["something", "else"]
>> s.kind_of?(Array)
=> true
kind_of?()
rispetto ad altre soluzioni? Alcune spiegazioni sui vantaggi della tua risposta rispetto ad altre sarebbero utili per i futuri lettori.
Sei sicuro che ha bisogno di essere un array? Potresti essere in grado di usare in respond_to?(method)
modo che il tuo codice funzioni per cose simili che non sono necessariamente array (forse qualche altra cosa numerabile). Se hai effettivamente bisogno di un array
, allora il post che descrive il Array#kind\_of?
metodo è il migliore.
['hello'].respond_to?('each')
respond_to?(:to_ary)
.
Invece di provare Array,
a convertire tutto ciò che ottieni in un livello Array,
, il tuo codice deve gestire solo un caso.
t = [*something] # or...
t = Array(something) # or...
def f *x
...
end
Ruby ha vari modi per armonizzare un'API che può accettare un oggetto o un Array di oggetti, quindi, ipotizzando perché vuoi sapere se qualcosa è un Array, ho un suggerimento.
L' operatore splat contiene molta magia che puoi cercare, oppure puoi semplicemente chiamare Array(something)
che aggiungerà un wrapper Array se necessario. È simile a [*something]
in questo caso.
def f x
p Array(x).inspect
p [*x].inspect
end
f 1 # => "[1]"
f [1] # => "[1]"
f [1,2] # => "[1, 2]"
Oppure, potresti usare lo splat nella dichiarazione del parametro e poi .flatten
, dandoti un diverso tipo di raccoglitore. (Del resto, potresti chiamare anche .flatten
sopra.)
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]"
E, grazie gregschlom , a volte è più veloce da usare Array(x)
perché quando è già un Array
non ha bisogno di creare un nuovo oggetto.
[*nil] => []
. Quindi potresti ritrovarti con un array vuoto.
Array(foo)
è molto più efficiente di[*foo]
[1,2,3].is_a? Array
restituisce true.
is_a?
a tutto questo thread. Il più vicino è un file [1,2,3].is_a? Enumerable
. Penso ancora che valga la pena avere questa risposta.
Sembra che tu stia cercando qualcosa che abbia un concetto di oggetti. Quindi consiglierei di vedere se lo è Enumerable
. Ciò garantisce anche l'esistenza di #count
.
Per esempio,
[1,2,3].is_a? Enumerable
[1,2,3].count
nota che, mentre size
, length
e count
tutto funziona per gli array, qui count
è il significato giusto - (per esempio, 'abc'.length
ed 'abc'.size
entrambi funzionano, ma 'abc'.count
non funzionano così).
Attenzione: una stringa is_a? Enumerabile, quindi forse questo non è quello che vuoi ... dipende dal tuo concetto di un oggetto come un array.
Provare:
def is_array(a)
a.class == Array
end
EDIT : L'altra risposta è molto meglio della mia.
Considera anche l'utilizzo di Array()
. Dalla Guida allo stile della community di Ruby :
Usa Array () invece del controllo Array esplicito o [* var], quando hai a che fare con una variabile che vuoi trattare come Array, ma non sei certo che sia un array.
# 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) }
to_a
viene chiamato su ogni argomento aggiunto al nuovo array, quindi Array({id: 100})
restituisce[[:id, 100]]