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 .flattensopra.)
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 Arraynon 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, lengthe counttutto funziona per gli array, qui countè il significato giusto - (per esempio, 'abc'.lengthed 'abc'.sizeentrambi funzionano, ma 'abc'.countnon 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_aviene chiamato su ogni argomento aggiunto al nuovo array, quindi Array({id: 100})restituisce[[:id, 100]]