Solidity – How to Convert String of Integers Separated by a Delimiter to Integer Array

contract-developmentoraclessolidity

Using Oraclize, I request a some external data in the form "1 2 3", i.e., space-separated integers (OR any other delimiter).

Indeed, these numbers could be requested one at a time, but this would be EXPENSIVE.

Now, to work with these integers, I need to convert them back to integers and store them inside an array.

I know the parseInt() function for converting a string to a number, but how to I break up the string into "1", "2", "3", such that I can parse the numbers and store them in an array?

Best Answer

You may use a library like stringutils or solidity-util to for that. For your special case, casting the string to bytes and manipulating like the following function will work.

contract MyContract{

    bytes tempNum ; //temporarily hold the string part until a space is recieved
    uint[] numbers;

    function splitStr(string str, string delimiter) constant returns (int []){ //delimiter can be any character that separates the integers 

        bytes memory b = bytes(str); //cast the string to bytes to iterate
        bytes memory delm = bytes(delimiter); 

        for(uint i; i<b.length ; i++){          

            if(b[i] != delm[0]) { //check if a not space
                tempNum.push(b[i]);             
            }
            else { 
                numbers.push(parseInt(string(tempNum))); //push the int value converted from string to numbers array
                tempNum = "";   //reset the tempNum to catch the net number                 
            }                
        }

        if(b[b.length-1] != delm[0]) { 
           numbers.push(parseInt(string(tempNum)));
        }
        return numbers;
    }
}

If you can't use parseInt you may use your own function to convert to uint as follow found here,

function bytesToUint(bytes b) constant returns (uint result) {

    result = 0;
    for (uint i = 0; i < b.length; i++) { 
        if (b[i] >= 48 && b[i] <= 57) {
            result = result * 10 + (uint(b[i]) - 48); 
        }
    }
    return result;
    }

Then instead of numbers.push(parseInt(string(tempNum))); you can use numbers.push(bytesToUint(tempNum));

Or you can look into the libraries code and use only the function you need. Those might be efficient.

Hope this helps!