Por alguna razón, la solidez no permite insertar valores en la matriz de memoria
El miembro "push" no está disponible en la memoria bytes32[] fuera del almacenamiento.
Aquí hay un código de contrato de muestra:
pragma solidity ^0.4.21;
contract Foo {
function getRange(uint n) public pure returns(uint[]) {
uint[] memory result;
for (uint i = 0; i < n; i++)
if (someCondition(i))
result.push(i);
return result;
}
}
Podría asignar la máxima matriz de tamaño posible n
y luego reducirla, pero puede afectar el rendimiento ( n
podría ser del orden de magnitud de 100000
mientras que la longitud final del resultado es 0..100
). Por ejemplo, someCondition
podría ser isPrime
. En este caso, tenemos un N grande (lo que hace imposible preasignar una matriz) y una pequeña lista de números primos resultantes.
¿Cómo se podría hacer?
Terminé preaplicando una matriz de tamaño n
y luego reduciéndola una vez que sé que es la longitud final:
function getRange(uint n) public pure returns(uint[]) {
uint tookCount = 0;
uint[] memory result = new uint[](n);
for (uint i = 0; i < n; i++)
if (someCondition(i)) {
result.push(i);
tookCount++;
}
uint[] memory trimmedResult = new uint[](tookCount);
for (uint j = 0; j < trimmedResult.length; j++) {
trimmedResult[j] = result[j];
}
return trimmedResult;
}
Las matrices dinámicas solo están disponibles en el almacenamiento, no en la memoria. En su caso, el tamaño de la result
matriz se conoce por adelantado ( n
). Entonces, puede simplemente declarar una matriz con una longitud de n
. Luego puedes llenarlo usando i
, que va de 0
an - 1
pragma solidity ^0.4.21;
contract Foo {
function getRange(uint n) public pure returns(uint[]) {
uint[] memory result = new uint[](n);
for (uint i = 0; i < n; i++)
result[i] = i;
return result;
}
}
que yo sé
push es solo para matrices de almacenamiento, no para matrices de memoria
del documento:
push: las matrices de almacenamiento dinámico y los bytes (no cadenas) tienen una función miembro llamada push que se puede usar para agregar un elemento al final de la matriz. La función devuelve la nueva longitud.
intentar
result[j]=keccak256(id);//declare j
Como tiene una condición en la iteración, agregaré esta clave en la respuesta de Henk:
pragma solidity ^0.4.21;
contract Foo {
function getRange(uint n) public pure returns(unit[] memory result) {
uint j = 0;
for (uint i = 0; i < n; i++)
if (someCondition(i))
result[j] = i;
j++;
}
}
Usar almacenamiento en lugar de memoria
pragma solidity ^0.4.21;
contract Foo {
function getRange(uint n) public view returns(uint[]) {
uint[] storage result;
for (uint i = 0; i < n; i++)
if (i> 1)
result.push(i);
return result;
}
}
uint[]
en la primera ranura.
Badr Bellaj
Alex Zhukovsky
Badr Bellaj
Alex Zhukovsky