Jaki jest właściwy sposób:
is_array("something") # => false (or 1)
is_array(["something", "else"]) # => true (or > 1)
lub uzyskać liczbę elementów w nim?
Jaki jest właściwy sposób:
is_array("something") # => false (or 1)
is_array(["something", "else"]) # => true (or > 1)
lub uzyskać liczbę elementów w nim?
Odpowiedzi:
Prawdopodobnie chcesz użyć kind_of()
.
>> s = "something"
=> "something"
>> s.kind_of?(Array)
=> false
>> s = ["something", "else"]
=> ["something", "else"]
>> s.kind_of?(Array)
=> true
kind_of?()
z innych rozwiązań? Niektóre wyjaśnienia na temat zalet twojej odpowiedzi w porównaniu z innymi byłyby pomocne dla przyszłych czytelników.
Czy na pewno musi to być tablica? Możesz być w stanie użyć, respond_to?(method)
aby twój kod działał dla podobnych rzeczy, które niekoniecznie są tablicami (być może jakieś inne rzeczy, które można policzyć). Jeśli naprawdę potrzebujesz array
, to post opisujący Array#kind\_of?
metodę jest najlepszy.
['hello'].respond_to?('each')
respond_to?(:to_ary)
.
Zamiast testować Array,
tylko konwersję tego, co dostajesz, na jeden poziom, Array,
więc Twój kod musi obsłużyć tylko jeden przypadek.
t = [*something] # or...
t = Array(something) # or...
def f *x
...
end
Ruby ma różne sposoby zharmonizowania interfejsu API, który może przyjmować obiekt lub tablicę obiektów, więc zgadując, dlaczego chcesz wiedzieć, czy coś jest tablicą, mam sugestię.
Ikona operatora zawiera wiele magii można sprawdzić, czy można po prostu zadzwonić Array(something)
, która doda opakowanie Array razie potrzeby. Podobnie jest [*something]
w tym jednym przypadku.
def f x
p Array(x).inspect
p [*x].inspect
end
f 1 # => "[1]"
f [1] # => "[1]"
f [1,2] # => "[1, 2]"
Lub możesz użyć ikony w deklaracji parametru, a następnie .flatten
, dając ci inny rodzaj kolektora. (W tym przypadku możesz też zadzwonić .flatten
powyżej).
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]"
Dzięki, dzięki gregschlom , czasem jest to szybsze w użyciu, Array(x)
ponieważ gdy już jest Array
, nie musi tworzyć nowego obiektu.
[*nil] => []
. Więc możesz skończyć z pustą tablicą.
Array(foo)
jest znacznie wydajniejsze niż[*foo]
[1,2,3].is_a? Array
ocenia na prawdę.
is_a?
do tego całego wątku. Najbliższy to [1,2,3].is_a? Enumerable
. Nadal uważam, że warto mieć tę odpowiedź.
Wygląda na to, że szukasz czegoś, co ma jakieś pojęcie o przedmiotach. Polecam więc sprawdzić, czy tak jest Enumerable
. To gwarantuje również istnienie #count
.
Na przykład,
[1,2,3].is_a? Enumerable
[1,2,3].count
pamiętać, że o ile size
, length
i count
cała praca na macierzach, count
to właściwy sens tutaj - (na przykład, 'abc'.length
i 'abc'.size
zarówno do pracy, ale 'abc'.count
nie działa w ten sposób).
Uwaga: ciąg jest_a? Wymienne, więc być może nie tego chcesz ... zależy od twojej koncepcji obiektu typu tablica.
Próbować:
def is_array(a)
a.class == Array
end
EDYCJA : Inna odpowiedź jest znacznie lepsza niż moja.
Rozważ również użycie Array()
. Z przewodnika po stylu społeczności Ruby :
Używaj Array () zamiast jawnego sprawdzania Array lub [* var], gdy masz do czynienia ze zmienną, którą chcesz traktować jako Array, ale nie masz pewności, że jest to tablica.
# 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
jest wywoływany dla każdego argumentu dodanego do nowej tablicy, więc Array({id: 100})
wraca[[:id, 100]]