Qual é o caminho certo para:
is_array("something") # => false (or 1)
is_array(["something", "else"]) # => true (or > 1)
ou para obter a contagem de itens?
Qual é o caminho certo para:
is_array("something") # => false (or 1)
is_array(["something", "else"]) # => true (or > 1)
ou para obter a contagem de itens?
Respostas:
Você provavelmente quer usar kind_of()
.
>> s = "something"
=> "something"
>> s.kind_of?(Array)
=> false
>> s = ["something", "else"]
=> ["something", "else"]
>> s.kind_of?(Array)
=> true
kind_of?()
outras soluções? Alguma explicação sobre os benefícios de sua resposta sobre os outros seria útil para futuros leitores.
Tem certeza de que precisa ser uma matriz? Você pode usá- respond_to?(method)
lo para que seu código funcione para coisas semelhantes que não são necessariamente matrizes (talvez alguma outra coisa enumerável). Se você realmente precisa de um array
, a publicação que descreve o Array#kind\_of?
método é a melhor.
['hello'].respond_to?('each')
respond_to?(:to_ary)
.
Em vez de testar uma Array,
conversão, basta converter o que você tiver em um nível, Array,
para que seu código precise lidar apenas com um caso.
t = [*something] # or...
t = Array(something) # or...
def f *x
...
end
O Ruby tem várias maneiras de harmonizar uma API que pode pegar um objeto ou uma matriz de objetos, portanto, adivinhando por que você quer saber se algo é uma matriz, tenho uma sugestão.
O operador splat contém muita mágica que você pode procurar ou pode simplesmente chamar, Array(something)
que adicionará um wrapper Array, se necessário. É semelhante [*something]
neste caso.
def f x
p Array(x).inspect
p [*x].inspect
end
f 1 # => "[1]"
f [1] # => "[1]"
f [1,2] # => "[1, 2]"
Ou você pode usar o splat na declaração de parâmetro e .flatten
, em seguida , fornecer um tipo diferente de coletor. (Nesse caso, você também pode ligar .flatten
acima.)
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, graças ao gregschlom , às vezes é mais rápido usar apenas Array(x)
porque, quando já é um Array
, não é necessário criar um novo objeto.
[*nil] => []
. Então você pode acabar com uma matriz vazia.
Array(foo)
é muito mais eficiente do que[*foo]
[1,2,3].is_a? Array
avalia como verdadeiro.
is_a?
todo esse tópico. O mais próximo é um [1,2,3].is_a? Enumerable
. Ainda acho que vale a pena ter essa resposta.
Parece que você está procurando algo que tenha algum conceito de itens. Eu, portanto, recomendo ver se é Enumerable
. Isso também garante a existência de#count
.
Por exemplo,
[1,2,3].is_a? Enumerable
[1,2,3].count
note que, enquanto size
, length
e count
todo o trabalho para arrays, count
é o significado aqui - (por exemplo, 'abc'.length
e 'abc'.size
tanto trabalho, mas 'abc'.count
não é assim que funciona).
Cuidado: uma string é_a? Enumerável, então talvez isso não seja o que você deseja ... depende do seu conceito de uma matriz como objeto.
Experimentar:
def is_array(a)
a.class == Array
end
EDIT : A outra resposta é muito melhor que a minha.
Considere também usar Array()
. No Guia de estilo da comunidade Ruby :
Use Array () em vez de verificação explícita de Array ou [* var], ao lidar com uma variável que você deseja tratar como uma matriz, mas não tem certeza de que é uma 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) }
to_a
é chamado em cada argumento adicionado à nova matriz, então Array({id: 100})
retorna[[:id, 100]]