Wäre es möglich, alle Werte eines Mappings oder Arrays (ohne Schleife) zu erhöhen?
Beispiel:
mapping(address => uint) score;
uint[] values;
function increase_scores() public {
// Example pseudo-code for mapping and array:
score.all += 1; // ??
values += 1; // Ex.Something like the python map(lambda x: x+1,list) ??
}
Bearbeiten : Um mehr Kontext bereitzustellen, habe ich eine Zuordnung mit Benutzern und Ergebnissen. Jedes Mal, wenn ich die Funktion raise_scores aufrufe , möchte ich die Punktzahl aller Benutzer des Mappings erhöhen. Daher möchte ich nicht das gesamte Array einschalten, da mir bei vielen Benutzern möglicherweise das Gas ausgeht.
Bearbeiten : Das Kartenbeispiel von Python ist auch keine gute Idee, da es am Ende über das gesamte Array oder Mapping iterieren muss. Es wird auch kein Benzin mehr haben. Bei der Schleife gibt es keinen Unterschied.
Wie Rob vorschlägt, können Sie die Werte im laufenden Betrieb berechnen, da das Iterieren einer Zuordnung nicht möglich ist und es teuer wäre, wenn es sich um ein Array handeln würde.
Angenommen, Sie haben mehrere Punktzahlen, die Adressen zugeordnet sind.
Adresse - Punktzahl
0x1 - 3
0x2 - 4
0x3 - 2
Ihre ursprüngliche Absicht war es, jedes Element des Mappings zu durchlaufen, um die Punktzahlen zu erhöhen, was nicht machbar ist.
Was Sie tun könnten, ist, eine Zustandsvariable hinzuzufügen uint scoreIncrement
, die verfolgt, wie oft die Punktzahl für alle Punktzahlen erhöht wurde.
function increase_scores() public {
scoreIncrement++;
}
Dann haben Sie eine Funktion, die den Score eines Elements plus das ScoreIncrement zurückgibt.
function getScore(address _a) public returns (uint){
return scores[_a] + scoreIncrement;
}
Anstatt also direkt auf ein Element der Scores-Zuordnung zuzugreifen, würden Sie diese Funktion aufrufen.
Sie könnten dem noch mehr Logik hinzufügen. Möglicherweise möchten Sie auch in Zukunft nicht jede einzelne Punktzahl erhöhen, die hinzugefügt wird. Vielleicht möchten Sie also auch mit Zeitstempeln oder Gruppenadressen spielen, sodass ein bestimmtes scoreIncrement nur bestimmte Adressen betrifft und nicht alle.
NEIN.
Es würde eine Iteration über eine Liste der Schlüssel erfordern und in jede zugeordnete Partitur schreiben. Es wäre im Maßstab unerschwinglich teuer.
Niemand kann ohne weitere Informationen genau vorschlagen, wie Sie Ihren Anwendungsfall ansprechen können (bearbeiten Sie Ihre Frage?), aber ich könnte vorschlagen, dass einige dieser Fälle mit Funktionen erreicht werden können, die ein wenig zeitbasierte oder ereignisbasierte Mathematik zur Berechnung durchführen Ergebnis im Handumdrehen.
Ist es möglich herauszufinden, was der Speicher sagen würde , wenn das Brute-Force-Update verwendet würde?
Anstatt den genauen Inhalt eines Speicherplatzes zurückzugeben, geben Sie eine Funktion des Speichers und der anderen Variablen zurück (z. B. wie viel Zeit vergangen ist).
AKTUALISIEREN
Anstatt
mapping(address => SomeStruct) public someStructs;
und ein "Brute-Force"-Update
function massiveUpdate() public onlyOwner ( for(i=0; i<number ...
Erwägen Sie, eine Berechnung für den gespeicherten Zustand auszuführen, um den aktuellen Zustand zu bestimmen. In diesem kleinen erfundenen Beispiel soll jeder im Spiel jedes Mal einen Punkt gewinnen, wenn ein neuer Block entdeckt wird. Wir werden es tun, ohne in den Speicher zu schreiben.
mapping(address => SomeStruct) someStructs; // not public
function getAScore(address key) public constant returns(uint) {
uint score = someStructs[key].score; // a property that needs periodic batch updates
uint lastUpated = someStructs[key].lastUpdated; // timeStamp of last update (as blockNumber)
uint elapsed = block.number - lastUpdated;
uint actualScore = score + elapsed;
return actualScore; // everyone receives +1 every 15 seconds.
}
Ich hoffe es hilft.
IB