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
; index
ist 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 push
oder delete
sollte ich die länge behalten müssen?
Bei meiner Lösung Map[msg.sender][0].my_length
wird die Anzahl der spitzen Strukturen von zurückgegeben Map[msg.sender]
.
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].length
existiert und geben Sie die Größe des entsprechenden Arrays an Ihren Schlüssel zurück. so Map[msg.sender].length
ist richtig, aber Map[msg.sender][0].length
nicht. denn in diesem zweiten Fall geben Sie die erste Struktur zurück, die keinen Längenparameter, sondern einen hat my_length
.
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.
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 uint
haben, und Sie müssen wissen, dass Sie durch diesen Vorgang mehr GAS verbrauchen.
Alper
Map[key].length
es tatsächlich existiert, also versuche ich, Variablen zu verwendenmy_length
, um den Überblick zu behalten. Es war ein TippfehlerMap[msg.sender][0].my_length
ist die richtige Zeile.