Erhöhen Sie alle Werte von Mapping oder Array ohne Schleife

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.

Zuordnungen sind nicht iterierbar, aber es ist möglich, eine Datenstruktur darüber zu implementieren. Dies ist ein Beispiel für ein iterierbares Mapping

Antworten (2)

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.

Beachten Sie, dass dies nur praktikabel ist, wenn die Erhöhung Benutzer einbeziehen soll, die noch nicht in der Zuordnung enthalten sind. (Ich vermute, dass die Punktzahl vielleicht nur für die aktuelle Gruppe von Spielern erhöht werden sollte und neue Spieler, die später hinzukommen, nicht von der Punktzahlerhöhung profitieren sollten.)
Exakt. Deshalb habe ich erwähnt, dass es möglicherweise noch ein paar weitere Schritte geben kann, je nachdem, was erreicht werden soll. Sie müssten nachverfolgen, wann jede Punkteerhöhung erfolgt ist, und sie nur auf Benutzer anwenden, deren Anmeldezeitstempel vor dem Datum liegt, an dem die Erhöhung vorgenommen wurde.
Irgendwelche Gedanken darüber, was passiert, wenn die Anzahl der Gruppen, denen ein Spieler angehört, nicht begrenzt ist? Ich meine, ich müsste das gesamte Array mit allen Gruppen durchlaufen, denen der Spieler angehört ... und vorausgesetzt, er kann Teil von Tausenden von Gruppen sein ... mir kann auch das Benzin ausgehen. Tut mir leid, die Frage zu erweitern, aber haben Sie eine Empfehlung für diesen Anwendungsfall?

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.

Hallo! Entschuldigung, aber was meinst du mit Brute-Force-Update? und nach Funktion des Speichers?