Möchten Sie ein tatsächliches Array oder nur etwas Array-ähnliches?
Kathy Van Stone
1
In Ruby gibt es keine Typensicherheit. Machen Sie sich keine Sorgen, dass Ihre Variable ein Array ist oder nicht. Die Methode sollte davon ausgehen, dass dies der Fall ist, und die Anzahl der Aufrufe
aufrufen
Bitte lesen Sie die Antworten von zgchurch und DigitalRoss, um mehr über Ruby zu erfahren.
Die Typprüfung ist für Java. Rufen Sie einfach count für die Variable auf. Schreiben Sie Komponententests, um sicherzustellen, dass die Methode wie erwartet funktioniert.
user132447
14
@ user132447 tatsächlich ist Java typsicher, so dass Sie sich keine Gedanken über das Überprüfen von Typen machen müssen
grinch
8
Ich habe dies jetzt abgelehnt, da ich nicht denke, dass dies eine gute Praxis in einer Sprache wie Ruby ist. Die Antwort von @zgchurch ist eindeutig eine viel idiomatischere Herangehensweise an die Frage. In solchen Fällen halte ich es für viel sinnvoller, herauszufinden, was das OP bedeutet, als ihm blind eine Schrotflinte zu geben ...
Per Lundberg
1
Warum sollten Sie 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.
AlbertEngelB
148
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.
In diesem Fall bin ich sicher, dass es sich um ein Array handelt. Aber schön, diese Methode auch zu kennen. +1
BuddyJoe
Interessante Idee, ich verwende Push / Pop für eine Datenstruktur. Würde etwas anderes als Arrays auf diese Methoden reagieren?
Drew
3
Wenn Sie etwas Array-ähnlicheres möchten, möchten Sie vielleicht respond_to?(:to_ary).
Andrew Grimm
21
Im Allgemeinen ist dies eine gute Vorgehensweise für die OO-Entwicklung. Ich habe gelesen, wo jemand im Grunde gesagt hat: Stellen Sie sich nicht vor, dass Sie Methoden für Ihre Objekte aufrufen. Sie senden ihnen Nachrichten. Wenn ein Objekt weiß, wie es auf Ihre Nachricht reagiert, ist es Ihnen egal, um welche Klasse es sich handelt oder ob es eine Methode mit diesem Namen hat oder ob es dynamisch eine Antwort über method_missing erstellt. Das Wichtigste ist, kann es auf Ihre Nachricht antworten? Dies ermöglicht eine bessere Abstraktion von Funktion und Implementierung. Sie können ändern, welches Objekt Sie später verwenden, solange es noch korrekt reagiert.
Nathan Long
2
Das einzige Problem dabei ist, dass ich überprüfen möchte, ob etwas indiziert iterierbar ist, sodass Arrays, verknüpfte Listen usw. cool wären, aber ich möchte keine Schlüsselwertspeicher wie Hashes?
Colton Voege
58
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 .flatteneine andere Art von Kollektor erhalten. (Für diese Angelegenheit könnten Sie auch .flattenoben 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 Arrayist, kein neues Objekt erstellen muss.
Was trägt dies zu den Antworten bei, die seit fast sieben Jahren auf der Website sind?
Martin Tournoij
6
@Carpetsmoker Es gibt keine präzise Antwort, auf die 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.
dipole_moment
4
Weißt du ... du hast tatsächlich Recht ... Ich hätte schwören können, dass ich das dort oben früher gesehen habe: - / Habe eine positive Bewertung!
Martin Tournoij
16
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, lengthund countalle arbeiten für Arrays, counthier die richtige Bedeutung ist - (zum Beispiel 'abc'.lengthund 'abc'.sizebeide arbeiten, aber 'abc'.countnicht 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.
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)}
Dies wird zu unerwarteten Ergebnissen führen , wenn ein Hash vorbei , weil to_aauf jedes Argument hinzugefügt , um das neue Array, so genannt wird , Array({id: 100})kehrt[[:id, 100]]
Antworten:
Sie möchten wahrscheinlich verwenden
kind_of()
.quelle
is_a?
undinstance_of?
. Siehe stackoverflow.com/questions/3893278/…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ötigenarray
, ist der Beitrag, der dieArray#kind\_of?
Methode beschreibt, am besten.quelle
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.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.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 .)Und dank Gregschlom ist es manchmal schneller, es einfach zu benutzen,
Array(x)
weil es, wenn es bereits einArray
ist, kein neues Objekt erstellen muss.quelle
[*nil] => []
. Möglicherweise erhalten Sie ein leeres Array.Array(foo)
ist viel effizienter als[*foo]
[1,2,3].is_a? Array
bewertet als wahr.quelle
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,
beachten Sie, dass, während
size
,length
undcount
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.
quelle
Versuchen:
EDIT : Die andere Antwort ist viel besser als meine.
quelle
Erwägen Sie auch die Verwendung
Array()
. Aus dem Ruby Community Style Guide :quelle
to_a
auf jedes Argument hinzugefügt , um das neue Array, so genannt wird ,Array({id: 100})
kehrt[[:id, 100]]