it-swarm.com.de

Anzahl, Größe, Länge ... zu viele Optionen in Ruby?

Ich kann keine definitive Antwort auf diese Frage finden und ich möchte sicherstellen, dass ich das bis zum "n-ten Level" verstehe :-)

 
 a = {"a" => "Hallo", "b" => "Welt"} 
 a.count # 2 
 a.size # 2 
 A.Länge # 2 
 
 A = [10, 20] 
 A.Anzahl # 2 
 A.size # 2 
 a.length # 2 
 

Also was soll man benutzen? Wenn ich wissen will, ob ein Element mehr als ein Element hat, ist es anscheinend egal, aber ich möchte sicherstellen, dass ich den wirklichen Unterschied verstehe. Dies gilt auch für Arrays. Ich bekomme die gleichen Ergebnisse.

Außerdem ist mir klar, dass Anzahl/Größe/Länge bei ActiveRecord unterschiedliche Bedeutungen haben. Ich bin hauptsächlich an puren Ruby (1.92) interessiert, aber wenn jemand den Unterschied, den AR macht, ausmachen möchte, wäre er auch dankbar.

Vielen Dank!

138
cbmeeks

Für Arrays und Hashes ist size ein Alias ​​für length . Sie sind Synonyme und machen genau dasselbe.

count ist vielseitiger - es kann ein Element oder Prädikat annehmen und nur die übereinstimmenden Elemente zählen.

> [1,2,3].count{|x| x > 2 }
=> 1

In dem Fall, in dem Sie keinen Parameter zum Zählen angeben , hat dies im Grunde den gleichen Effekt wie die Aufruflänge. Es kann jedoch einen Leistungsunterschied geben.

Wir können aus dem Quellcode für Array ersehen, dass sie fast genau dasselbe tun. Hier ist der C-Code für die Implementierung von array.length:

static VALUE
rb_ary_length(VALUE ary)
{
    long len = RARRAY_LEN(ary);
    return LONG2NUM(len);
}

Und hier ist der relevante Teil aus der Implementierung von array.count:

static VALUE
rb_ary_count(int argc, VALUE *argv, VALUE ary)
{
    long n = 0;

    if (argc == 0) {
        VALUE *p, *pend;

        if (!rb_block_given_p())
            return LONG2NUM(RARRAY_LEN(ary));

        // etc..
    }
}

Der Code für array.count Führt einige zusätzliche Überprüfungen durch, ruft jedoch am Ende genau denselben Code auf: LONG2NUM(RARRAY_LEN(ary)).

Hashes ( Quellcode ) scheinen dagegen keine eigene optimierte Version von count zu implementieren, also die Implementierung von Enumerable ( Quellcode) ) wird verwendet, wobei alle Elemente durchlaufen und einzeln gezählt werden.

Im Allgemeinen empfehle ich die Verwendung von length (oder seines Alias ​​size) anstelle von count, wenn Sie wissen möchten, wie viele Elemente insgesamt vorhanden sind.


Bei ActiveRecord gibt es dagegen wichtige Unterschiede . schau dir diesen Beitrag an:

192
Mark Byers

Es gibt einen entscheidenden Unterschied für Anwendungen, die Datenbankverbindungen verwenden.

Wenn Sie viele ORMs (ActiveRecord, DataMapper usw.) verwenden, wird allgemein verstanden, dass .size eine Abfrage generiert, die alle Elemente aus der Datenbank anfordert ('select * from mytable') und anschließend die Anzahl der Elemente angibt Dies führt dazu, dass .count eine einzelne Abfrage generiert ('select count (*) from mytable'), die erheblich schneller ist.

Weil diese ORMs so weit verbreitet sind, folge ich dem Prinzip des geringsten Erstaunens. Wenn ich bereits etwas im Speicher habe, verwende ich im Allgemeinen .size und wenn mein Code eine Anforderung an eine Datenbank (oder einen externen Dienst über eine API) generiert, verwende ich .count.

10
stef

In den meisten Fällen (z. B. Array oder String ) ist size ein Alias für length.

count kommt normalerweise von Enumerable und kann einen optionalen Prädikatblock annehmen. Also enumerable.count {cond} ist [ungefähr] (enumerable.select {cond}).length - es kann natürlich die Zwischenstruktur umgehen, da es nur die Anzahl der übereinstimmenden Prädikate benötigt.

Hinweis: Ich bin nicht sicher, ob count Forces eine Auswertung der Aufzählung ist, wenn der Baustein nicht angegeben ist oder wenn es möglich ist, einen Kurzschluss nach length .

Bearbeiten (und danke an Marks Antwort!): count ohne einen Block (zumindest für Arrays) geht nicht eine Auswertung erzwingen. Ich nehme an, ohne formales Verhalten ist es "offen" für andere Implementierungen, wenn das Erzwingen einer Evaluierung ohne Prädikat überhaupt überhaupt sinnvoll ist.

7
user166390

Ich fand eine gute Antwort unter http://blog.hasmanythrough.com/2008/2/27/count-length-size

In ActiveRecord gibt es verschiedene Möglichkeiten, um herauszufinden, wie viele Datensätze sich in einer Zuordnung befinden, und es gibt einige geringfügige Unterschiede in der Funktionsweise.

post.comments.count - Bestimmen Sie die Anzahl der Elemente mit einer SQL COUNT-Abfrage. Sie können auch Bedingungen angeben, um nur eine Teilmenge der zugeordneten Elemente zu zählen (z. B.: conditions => {: author_name => "josh"}). Wenn Sie einen Zähler-Cache für die Zuordnung einrichten, gibt #count diesen zwischengespeicherten Wert zurück, anstatt eine neue Abfrage auszuführen.

post.comments.length - Lädt immer den Inhalt der Zuordnung in den Speicher und gibt dann die Anzahl der geladenen Elemente zurück. Beachten Sie, dass hierdurch keine Aktualisierung erzwungen wird, wenn die Zuordnung zuvor geladen wurde und neue Kommentare auf eine andere Weise erstellt wurden (z. B. Comment.create (...) anstelle von post.comments.create (...)).

post.comments.size - Dies funktioniert als Kombination der beiden vorherigen Optionen. Wenn die Auflistung bereits geladen wurde, gibt sie ihre Länge zurück, genau wie beim Aufrufen von #length. Wenn es noch nicht geladen wurde, ist es wie der Aufruf von #count.

Auch ich habe eine persönliche Erfahrung:

<%= h(params.size.to_s) %> # works_like_that !
<%= h(params.count.to_s) %> # does_not_work_like_that !
5
profimedica

Es gibt verschiedene Möglichkeiten, um herauszufinden, wie viele Elemente in einem Array wie .length, .count und .size. Es ist jedoch besser, array.size eher, als array.count. Weil .size ist leistungsfähiger.

2
Venkat M

Mark Byers Antwort wird erweitert. In Ruby der Methode array.size ist ein Alias ​​für die Array # length -Methode. Es gibt keinen technischen Unterschied bei der Verwendung einer dieser beiden Methoden. Möglicherweise sehen Sie auch keinen Leistungsunterschied. Das array.count erledigt den gleichen Job, jedoch mit einigen zusätzlichen Funktionen Array # count

Es kann verwendet werden, um auf der Grundlage einer bestimmten Bedingung insgesamt keine Elemente abzurufen. Count kann auf drei Arten aufgerufen werden:

Array # count # Gibt die Anzahl der Elemente im Array zurück

Array # count n # Gibt die Anzahl der Elemente mit dem Wert n in Array zurück

Array # count {| i | i.even?} Gibt die Anzahl basierend auf der für jedes Elementarray aufgerufenen Bedingung zurück

array = [1,2,3,4,5,6,7,4,3,2,4,5,6,7,1,2,4]

array.size     # => 17
array.length   # => 17
array.count    # => 17

Hier machen alle drei Methoden den gleichen Job. Hier jedoch wird das count interessant.

Angenommen, ich möchte herausfinden, wie viele Array-Elemente das Array mit dem Wert 2 enthält.

array.count 2    # => 3

Das Array enthält insgesamt drei Elemente mit dem Wert 2.

Jetzt möchte ich alle Array-Elemente größer als 4 finden

array.count{|i| i > 4}   # =>6

Das Array enthält insgesamt 6 Elemente, die größer als 4 sind.

Ich hoffe, es gibt einige Informationen über count Methode.

1
Prabhakar