¿Cuál es la forma más eficiente de analizar una cadena de enteros en una matriz?

Realizo una consulta de Oracle en un archivo XML y recibo esta cadena a cambio:

["31", "25", "24"]

¿Cuál sería la forma más eficiente de analizar esta cadena y almacenar los números en una uint8matriz utilizando la cantidad mínima de gas?

¿O hay una mejor manera de abordar este problema?
Si es así, incluya ejemplos.

Nota:
No busco procesar millones de números de esta manera, solo alrededor de 100 más o menos.

¿Desea convertir una matriz de cadenas en una matriz de enteros? ¿O tienes esta matriz como una cadena?
Derecho. Quiero extraer los números de esta cadena y ponerlos en una uint8matriz.

Respuestas (1)

Dado que el tipo devuelto es a string, los números se almacenan en una bytesmatriz dinámica. Esto significa que cada personaje ocupa un solo byteespacio . La representación de números ASCII/UTF-8 bits aumenta linealmente, puede analizar los números de la siguiente manera:

pragma solidity ^0.4.24;

contract NumParser {
    string[] public numArray;
    uint256[] public shouldBe;

    constructor() public {
        numArray.push("31");
        numArray.push("25");
        numArray.push("24");
        shouldBe.push(31);
        shouldBe.push(25);
        shouldBe.push(24);
        uint256[] memory result = parseNums(numArray);
        for (uint256 i = 0; i < result.length; i++) {
            assert(result[i] == shouldBe[i]);
        }
    }

    function parseNums(string[] numsToParse) internal pure returns (uint256[]) {
        uint256[] memory parsed = new uint256[](numsToParse.length);
        for (uint256 i = 0; i < numsToParse.length; i++) {
            bytes memory temp = bytes(numsToParse[i]);
            for (uint256 j = 0; j < temp.length; j++) {
                parsed[i] += (uint256(temp[j]) - 48) * (10**(temp.length - 1 - j));
            }
        }
        return parsed;
    }
}

El constructorcontiene una prueba de verificación de que la función funciona correctamente. La función que desea utilizar es la parseNumsfunción .

EDITAR: debe cambiar su pregunta original para incluir que está recibiendo la matriz en stringformato .

He modificado mi función para trabajar con su matriz de la siguiente manera:

pragma solidity ^0.4.24;

contract NumParser {
    string public numArray;
    uint256[] private tempContainer;
    uint256[] public shouldBe;

    constructor() public {
        numArray = "[\"31\", \"25\", \"24\"]";
        shouldBe.push(31);
        shouldBe.push(25);
        shouldBe.push(24);
        uint256[] memory result = parseNums(numArray);
        tempContainer.length = 0;
        for (uint256 i = 0; i < result.length; i++) {
            assert(result[i] == shouldBe[i]);
        }
    }

    function parseNums(string numsToParse) internal returns (uint256[]) {
        bytes memory converted = bytes(numsToParse);
        for (uint256 i = 0; i < converted.length; i++) {
            if (converted[i] == 34) {
                tempContainer.push(0);
                uint256 j = i + 1;
                for (; converted[j] != 34; j++) {
                    tempContainer[tempContainer.length - 1] += (uint256(converted[j]) - 48);
                    tempContainer[tempContainer.length - 1] *= 10;
                }
                tempContainer[tempContainer.length - 1] /= 10;
                i = j;
            }
        }
        return tempContainer;
    }
}

Tenga en cuenta que procesar una solicitud stringcomo esta es bastante costoso. Tampoco puede usar una memorymatriz en comparación con la primera solución porque las memorymatrices deben tener un tamaño predeclarado, mientras que no puede encontrar la cantidad de números que obtendrá en su matriz a partir de la cadena sin procesar.

Esto también aumenta el costo del gas, por lo que recomendaría poner a cero la longitud como se muestra en el constructorpara reducir el costo.

Esto resuelve el problema de convertir una cadena de números a unidades. Pero mi principal problema aquí es tomar la cadena ["31", "25", "24"]y extraer los números de allí y ponerlos en una uint8matriz. Entonces, supongo, ¿qué habría que hacer para ignorar los caracteres [, ], "y ,mientras se siguen extrayendo los números y convirtiéndolos en uint8s?
Su pregunta es ambigua, nunca especifica que es stringni la tiene en formato de escape, es decir: "[\"31\", \"25\", \"24\"]"edité mi respuesta de acuerdo con sus especificaciones adicionales.