Aumente todos los valores de mapeo o matriz sin bucle

¿Sería posible aumentar todos los valores de una asignación o matriz (sin bucle)?

Ejemplo:

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) ??
}

Editar : para proporcionar más contexto, tengo un mapeo con usuarios y puntajes. Cada vez que llamo a la función Increase_scores , me gustaría aumentar el puntaje de todos los usuarios del mapeo. Por lo tanto, no me gustaría hacer un bucle en la matriz completa, ya que podría quedarme sin gasolina, si hay muchos usuarios.

Editar : el ejemplo del mapa de python tampoco es una buena idea, ya que al final tiene que iterar sobre toda la matriz o el mapeo ... también se quedará sin gasolina. No hay diferencia con el bucle.

Las asignaciones no son iterables, pero es posible implementar una estructura de datos encima de ellas. Este es un ejemplo de mapeo iterable

Respuestas (2)

Como sugiere Rob, lo que podría hacer, ya que iterar un mapeo no es posible, y si fuera una matriz, sería costoso, es calcular los valores sobre la marcha.

Digamos que tiene varios puntajes asignados a direcciones.

Dirección - Puntuación

0x1 - 3

0x2 - 4

0x3 - 2

Su intención original era iterar sobre cada elemento del mapeo para aumentar los puntajes, lo cual no es factible.

Lo que podría hacer es agregar una variable de estado uint scoreIncrementque realice un seguimiento de cuántas veces se ha incrementado el puntaje para todos los puntajes.

function increase_scores() public {
    scoreIncrement++;
}

Luego, tiene una función que devuelve la puntuación de un elemento, más el incremento de puntuación.

function getScore(address _a) public returns (uint){
  return scores[_a] + scoreIncrement;
}

Entonces, en lugar de acceder directamente a un elemento del mapeo de puntajes, llamarías a esta función.

Podría agregar aún más lógica a esto. Es posible que no desee aumentar cada puntaje que se agrega en el futuro también. Por lo tanto, es posible que también desee jugar con marcas de tiempo o direcciones de grupo, por lo que un incremento de puntaje determinado solo afecta a ciertas direcciones y no a todas.

Tenga en cuenta que esto solo es viable si el aumento pretende incluir usuarios que aún no están en el mapeo. (Supongo que tal vez la puntuación debería aumentar solo para el conjunto actual de jugadores, y los nuevos jugadores que se unan más tarde no deberían beneficiarse del aumento de puntuación).
Exactamente. Es por eso que mencioné que podría haber algunos pasos más involucrados en esto, dependiendo de lo que se quiera lograr. Tendrían que realizar un seguimiento de cuándo se realiza cada aumento de puntaje, y solo aplicarlo a los usuarios cuya marca de tiempo de registro es anterior a la fecha en que se realizó el aumento.
¿Alguna idea sobre qué sucede si el número de grupos a los que un jugador es miembro no es límite? Quiero decir que tendría que iterar en la matriz completa con todos los grupos de los que el jugador es miembro... y suponiendo que pueda ser parte de miles de grupos... también puedo quedarme sin combustible. Lamento extender la pregunta, pero ¿tiene alguna recomendación en ese caso de uso?

No.

Requeriría una iteración sobre una lista de claves y escrituras en cada puntuación asignada. Sería prohibitivamente caro a escala.

Nadie puede sugerir con precisión cómo abordar su caso de uso sin más información (¿editar su pregunta?), pero podría sugerir que algunos de estos casos se pueden lograr con funciones que hacen un poco de matemáticas basadas en tiempo o eventos para calcular el resultado sobre la marcha.

¿Es posible averiguar qué diría el almacenamiento si se usara la actualización de fuerza bruta?

En lugar de devolver el contenido exacto de una ubicación de almacenamiento, devuelva una función del almacenamiento y las otras variables (cuánto tiempo ha pasado, por ejemplo).

ACTUALIZAR

En lugar de

mapping(address => SomeStruct) public someStructs;

y una actualización de "fuerza bruta"

function massiveUpdate() public onlyOwner ( for(i=0; i<number ...

Considere ejecutar un cálculo en el estado almacenado para determinar el estado actual . En este pequeño ejemplo artificial, se supone que todos en el juego ganan un punto cada vez que se descubre un nuevo bloque. Lo haremos sin escribir en el almacenamiento.

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.
}

Espero eso ayude.

¡Hola! lo siento, pero ¿qué quieres decir con actualización de fuerza bruta? y por función del almacenamiento?