Könnte die Mapping-Datenstruktur die Anzahl der Elemente zurückgeben, auf die sie zeigt?

Zum Beispiel das folgende Codestück von https://ethereum.stackexchange.com/a/10763/4575 . Ich habe neue Zeilen hinzugefügt, auf die folgt //*.

pragma solidity ^0.4.2;
contract test {    
  struct my_struct {
    int a;
    int my_length; //*to keep track of the length.
  }

  mapping (address=>my_struct[]) Map;

  function fill_map(my_struct struct1,my_struct struct2) internal  {    
    Map[msg.sender].push(struct1);
    Map[msg.sender][0].my_length = Map[msg.sender][0].my_length + 1;//*

    Map[msg.sender].push(struct2);   
    Map[msg.sender][0].my_length = Map[msg.sender][0].my_length + 1;//*

    Map[msg.sender].push(struct3);//*  
    Map[msg.sender][0].my_length = Map[msg.sender][0].my_length + 1;//*

    delete Map[id][2]; //*struct3 will be removed.
    Map[msg.sender][0].my_length = Map[msg.sender][0].my_length - 1;//*
  }
}

Ich kann Daten wie folgt erhalten: Map[id][index].a; indexist eine ganze Zahl. In diesem Beispiel kann es 0 (für struct1) oder 1 (für struct2) sein.

Wie wir wissen, könnte Java die Anzahl der Objekte in einer Liste zurückgeben:

String[] array = new String[10];
int size = array.length;

Gibt es etwas Ähnliches wie: Map[id].length? oder manuell nach jedem pushoder deletesollte ich die länge behalten müssen?

Bei meiner Lösung Map[msg.sender][0].my_lengthwird die Anzahl der spitzen Strukturen von zurückgegeben Map[msg.sender].

Antworten (3)

Es gibt einige Fehler (oder ich habe Ihre Frage nicht gut verstanden) in Ihrem vorherigen Code und ich denke auch in Ihrer Frage.

In Ihrem Fall haben Sie eine Karte von Arrays. so Map[key].lengthexistiert und geben Sie die Größe des entsprechenden Arrays an Ihren Schlüssel zurück. so Map[msg.sender].lengthist richtig, aber Map[msg.sender][0].lengthnicht. denn in diesem zweiten Fall geben Sie die erste Struktur zurück, die keinen Längenparameter, sondern einen hat my_length.

Ahh mein Fehler, tut mir leid für die Verwirrung. Ich wusste nicht, dass Map[key].lengthes tatsächlich existiert, also versuche ich, Variablen zu verwenden my_length, um den Überblick zu behalten. Es war ein Tippfehler Map[msg.sender][0].my_lengthist die richtige Zeile.

Sie können weder die Anzahl der zugeordneten Schlüssel noch eine Liste der Schlüssel abrufen, die Daten zugeordnet sind.

Sie können eine Liste mit Schlüsseln in einem separaten Array verwalten, während Sie Daten in eine Zuordnung einfügen, und dann können Sie die Anzahl indirekt abrufen, indem Sie fragen, wie lang der Index ist.

Wenn Sie Ereignisemitter verwenden, um Zustandsänderungen zu melden, können Sie oft davon ausgehen, dass der Vertrag selbst die Zählung oder Liste nicht benötigt und die Clients keine weitere Hilfe vom Vertrag benötigen.

Whoa, die Frage hat sich sehr verändert. Ich bin verwirrt darüber, was wir zu erreichen versuchen. Wir könnten herausfinden, wie viele Strukturen in einer gegebenen Adresskarte (Array von Strukturen) gespeichert sind, aber nicht, wie viele Adressen Strukturen haben. Hoffe das macht Sinn.

Ich habe die Frage so verstanden, ob Sie die Länge der Zuordnung erhalten können oder nicht. Falls ja, funktioniert die folgende Anweisung:

Map.length

Leider sind Mappings in Solidity nicht iterierbar und haben keine Längen- oder Anzahleigenschaften, wie Sie hier in der offiziellen Dokumentation nachlesen können .

Eine Lösung besteht darin, die Größe manuell zu verfolgen, indem Sie eine Zustandsvariable deklarieren und sie erhöhen/verringern, wenn Sie eine Push-/Löschoperation auf der Zuordnung haben.

Der Code wird in etwa so aussehen:

uint mapSize;
// after a push operation
mapSize++;
// after a delete operation
mapSize--;

Sie müssen wissen, dass die Kartengröße nicht verwendet werden kann, um die Karte zu indizieren, die Sie haben, selbst wenn Sie den Schlüssel als uinthaben, und Sie müssen wissen, dass Sie durch diesen Vorgang mehr GAS verbrauchen.