Was ist der richtige Weg zu:
is_array("something") # => false (or 1)
is_array(["something", "else"]) # => true (or > 1)
oder um die Anzahl der darin enthaltenen Elemente zu ermitteln?
Was ist der richtige Weg zu:
is_array("something") # => false (or 1)
is_array(["something", "else"]) # => true (or > 1)
oder um die Anzahl der darin enthaltenen Elemente zu ermitteln?
Antworten:
Sie möchten wahrscheinlich verwenden kind_of()
.
>> s = "something"
=> "something"
>> s.kind_of?(Array)
=> false
>> s = ["something", "else"]
=> ["something", "else"]
>> s.kind_of?(Array)
=> true
kind_of?()
andere Lösungen verwenden? Einige Erklärungen zu den Vorteilen Ihrer Antwort gegenüber anderen wären für zukünftige Leser hilfreich.
Sind Sie sicher , dass es muss ein Array sein? Möglicherweise können Sie verwenden, respond_to?(method)
damit Ihr Code für ähnliche Dinge funktioniert, die nicht unbedingt Arrays sind (möglicherweise eine andere enumberable Sache). Wenn Sie tatsächlich eine benötigen array
, ist der Beitrag, der die Array#kind\_of?
Methode beschreibt, am besten.
['hello'].respond_to?('each')
respond_to?(:to_ary)
.
Anstatt nur zu testen, Array,
konvertieren Sie alles, was Sie erhalten, in eine Ebene, Array,
sodass Ihr Code nur den einen Fall behandeln muss.
t = [*something] # or...
t = Array(something) # or...
def f *x
...
end
Ruby hat verschiedene Möglichkeiten, eine API zu harmonisieren, die ein Objekt oder ein Array von Objekten aufnehmen kann. Wenn Sie also raten, warum Sie wissen möchten, ob es sich bei einem Array um ein Array handelt, habe ich einen Vorschlag.
Der Splat- Operator enthält viel Magie, die Sie nachschlagen können, oder Sie können einfach aufrufen Array(something)
, um bei Bedarf einen Array-Wrapper hinzuzufügen. Es ist ähnlich wie [*something]
in diesem einen Fall.
def f x
p Array(x).inspect
p [*x].inspect
end
f 1 # => "[1]"
f [1] # => "[1]"
f [1,2] # => "[1, 2]"
Oder Sie können den Splat in der Parameterdeklaration verwenden und dann .flatten
eine andere Art von Kollektor erhalten. (Für diese Angelegenheit könnten Sie auch .flatten
oben anrufen .)
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]"
Und dank Gregschlom ist es manchmal schneller, es einfach zu benutzen, Array(x)
weil es, wenn es bereits ein Array
ist, kein neues Objekt erstellen muss.
[*nil] => []
. Möglicherweise erhalten Sie ein leeres Array.
Array(foo)
ist viel effizienter als[*foo]
[1,2,3].is_a? Array
bewertet als wahr.
is_a?
in diesem gesamten Thread verwiesen wird. Der nächste ist a [1,2,3].is_a? Enumerable
. Ich denke immer noch, dass es sich lohnt, diese Antwort zu haben.
Es hört sich so an, als ob Sie nach etwas suchen, das ein Konzept von Gegenständen hat. Ich würde daher empfehlen zu sehen, ob es ist Enumerable
. Das garantiert auch die Existenz von #count
.
Zum Beispiel,
[1,2,3].is_a? Enumerable
[1,2,3].count
beachten Sie, dass, während size
, length
und count
alle arbeiten für Arrays, count
hier die richtige Bedeutung ist - (zum Beispiel 'abc'.length
und 'abc'.size
beide arbeiten, aber 'abc'.count
nicht funktioniert ähnlich).
Achtung: Ein String ist_a? Aufzählbar, vielleicht ist dies nicht das, was Sie wollen ... hängt von Ihrem Konzept eines Array-ähnlichen Objekts ab.
Versuchen:
def is_array(a)
a.class == Array
end
EDIT : Die andere Antwort ist viel besser als meine.
Erwägen Sie auch die Verwendung Array()
. Aus dem Ruby Community Style Guide :
Verwenden Sie Array () anstelle der expliziten Array-Prüfung oder [* var], wenn Sie mit einer Variablen arbeiten, die Sie als Array behandeln möchten, aber nicht sicher sind, ob es sich um ein Array handelt.
# 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
auf jedes Argument hinzugefügt , um das neue Array, so genannt wird , Array({id: 100})
kehrt[[:id, 100]]