0

I have a struct

    struct lineItem {
        string idNo;
        string date;
        string code;
        string docCode;
        string vendorNumber;
        string invoiceDate;
        string typeOfTransaction;
    }

I have a mapping

    mapping(string => lineItem[]) lineItems;//here string will be the user who adds data to this

So i have to filter the mapping according to the username given and after that i have to filter those data having idNo same as the input

      function getByInternalDocNo(string memory creator,string memory docNo,string memory typeOfFilter) public view returns(lineItem[] memory,vatDetails[] memory){
        uint count = 0;
        // bool[] memory res = new bool[](lineItems[creator].length);
        for (uint index = 0;index<lineItems[creator].length;index++){
            if(keccak256(bytes(lineItems[creator][index].idNo))==keccak256(bytes(docNo))) {
                count++;
            }
        }
        lineItem[] memory res1 = new lineItem[](count+1);
        vatDetails[] memory res2 = new vatDetails[](count+1);
        count = 0;
        for (uint index = 0;index<lineItems[creator].length;index++){
            if(keccak256(bytes(lineItems[creator][index].idNo))==keccak256(bytes(docNo))) {
                res1[count] = lineItems[creator][index];
                res2[count] = vatDetail[creator][index];
                count++;
            }
        }
        return (res1,res2);
    }

Now i want to make this function a bit more generic for all type of filters i.e. to check whether coCode is equal to given value or not.So,i wanted to do something like this

lineItems[creator][index][typeOfFilter]// will give error


and use this to compare it with the input value.So how do i do this?

1

well, given that all the members of your struct are of the same type, string, one way to do it would be to use an enum and an array of strings:

enum fields {idNo, date, code, docCode, vendorNumber, invoiceDate, typeOfTransaction}
struct lineItem {
   string[8] data;
}

then you can do

function getByInternalDocNo(string memory creator,string memory docNo, fields typeOfFilter) public view returns(lineItem[] memory,vatDetails[] memory){

and

lineItems[creator][index].data[uint256(typeOfFilter)];

note that you do need to manually cast the enum to a uint.

  • I'm sending the args ["abc","1221","idNo"],for which it is throwing error INVALID_ARGUMENT – alia Sep 12 at 4:44
  • enums are a user-friendly way of representing (usually) an ordered list of numbers. So in my example code idNo is actually the integer 0, date is 1, code is 2 etc.. so you need ["abc","1221",0] for your example depending on which language you're using you may be able to recreate the enum to make the code look more similar. if you really wanted to use an actual string here, you'll need to do some sort of lookup. I'd strongly recommend doing that off chain, although it would be possible, if expensive, on-chain. what language are you using to call solidity? – Zakalwe Sep 13 at 6:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.