0

Lottery time! At every new lottery initialized, each User is given n tickets. All the participants tickets are registered in a mapping called "allEntered" which collects tickets from every lottery. How do I return user's tickets for a given Lottery ID?

uint256 public currentLottery = 3;

struct Ticket {
        uint256 ticket_id;         
        address ticketOwner;
        uint256 lottery_id;  
    }

mapping(address => Ticket[]) public allEntered;

I wished to cycle through all user's ticket, check if lottery_id == currentLottery and in that case push the Ticket (or the ticket ID) in a new array to be returned. But it would be a dynamic memory array, which is not possible in Solidity. Code: Let's assume I already know the qty of user tickets because I've been smart when distributing them (although it would be nice to have a way to retrieve this number dynamically).

//This doesn't work because "push" is for dynamic arrays
function getMyCurrentTickets() public view returns(Ticket[] memory){
        Ticket[] memory myTk = new Ticket[](myKnownQty); //I wish this length was retrieved or dynamic
        for(uint i; i<allEntered[msg.sender].length; i++){
            if(allEntered[msg.sender][i].lottery_id == currentLottery){
                myTk.push(allEntered[msg.sender][i]);
            }
        }
        return myTk;
    }

//This doesn't work either because produces blank entries in the returned array
function getMyCurrentTickets() public view returns(Ticket[] memory){
        Ticket[] memory myTk = new Ticket[](allEntered[msg.sender].length);
        for(uint i; i<allEntered[msg.sender].length; i++){
            if(allEntered[msg.sender][i].lottery_id == currentLottery){
                myTk[i] = allEntered[msg.sender][i];
            }
        }
        return myTk;
    }

It's one whole day I'm struggling with workarounds but then I have the problem to reset the workarounds, and you cant just delete mappings, but this is another problem... Any ideas to help a noob?

2 Answers 2

0

I'm trying another route right now: a mapping of that mapping.

mapping (uint256 => mapping(address => Ticket[])) public lotteries;
//where the main unit256 key is the lottery_id
0
function getMyCurrentTickets() public view returns(Ticket[] memory) {
    uint256 ticketCount;
    Ticket[] memory tempTk = new Ticket[](allEntered[msg.sender].length);
    
    // First, filter the tickets and populate the temporary array
    for(uint i = 0; i < allEntered[msg.sender].length; i++) {
        if(allEntered[msg.sender][i].lottery_id == currentLottery) {
            tempTk[ticketCount] = allEntered[msg.sender][i];
            ticketCount++;
        }
    }
    
    // Now, we create a new array with the exact length as there are tickets
    Ticket[] memory myTk = new Ticket[](ticketCount);
    for(uint i = 0; i < ticketCount; i++) {
        myTk[i] = tempTk[i];
    }

    return myTk;
}

This function works in two steps:

  1. It loops over all the tickets and fills up a temporary array while counting how many tickets belong to the current lottery.
  2. It then creates a second array with the size of the count of relevant tickets and copies the tickets over.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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