Solidity – How to Filter Through an Array of Structs?

arrayscontract-developmentsoliditystructtransactions

I want a way to store an array of structs. And then I want the ability to filter through this array and pick out a subset of items where a certain struct parameter named foo == bar for example.

Is this possible in solidity? Are there any limitations on how large my original my array is and the number of returned items?

Lastly, because this would only read from the ledger, it should not cost any gas to execute correct?

Thank you.

Best Answer

As I understand its possible with followings,

Are there any limitations on how large my original my array

The limitation to contracts' storage is the limitation for this as well - i.e. 2^261 bytes. You may refer this question for contract storage limitation.

number of returned items?

There are two limitations; what solidity has allowed to return from a function which has a good read here and what your client machine used to connect to the ethereum network can handle in it's memory.

because this would only read from the ledger, it should not cost any gas to execute correct

This depends on your requirement. If what you want is just to read without a transaction involved (to display locally or so) it won't cost gas. But although the function is constant, if you need it to be used within a transaction (let's say you call non-constant function and within that function you use this constan function to verify something ) this may still cost gas. A good read regarding this can be found in this question.

code would look like something similar to this, depending on your requirement it may change

MyStruct[] myStructArray;

function checkArray() constant returns(bool[]){ // change on what you need to return

    bool[] checker; // change on what you need to return

    for(uint i = 0; i<myStructArray.length; i++){
        if(myStructArray[i].foo == bar){
            checker[i]=true; //or whatever you want to do if it matches
        }
        else{
            checker[i]=false;
        }
    }
    return checker;
}