Search code examples
ethereumsolidity

Returning arbitraty length array of structs in Solidity


In a contract i'm trying to implement some kind of recursivity of struct.

I have a map of wallets addresses that correspond to structs of type Ticket.

struct Ticket {
        uint256 ticketId;
        string firstname;
        string lastname;
    }
mapping (address => Ticket) tickets;

my problem with this solution is that i don't know how to return every ticket that have have a same address.

function setTicket(address _address, string memory _firstname, string memory _lastname) public returns(uint256){
        
        uint256 ticketNewId = uint256(keccak256(abi.encodePacked(block.timestamp, block.difficulty)));
        Ticket storage ticket = tickets[_address];
        ticket.firstname = _firstname;
        ticket.lastname = _lastname;
        ticket.ticketId = ticketNewId;
        ticketaccts.push(_address);
        return ticketNewId;
    }
    
    function getTickets() view public returns(address[] memory){
        return ticketaccts;
    }
    
    function getTicket(address _address) view public returns (Ticket memory){
        return (tickets[_address]);
    }

here getTicket() return the last ticket with the _address given. but what i want is return all the ticket with the same _address How can i do that ?


Solution

  • in the end the solution i choose is the following:

    function getTicketByAddress(address _address) public view returns (Ticket[] memory){ 
            Ticket[] memory ticketByAddress = new Ticket[](tickets[_address].length);
    
            uint numberOfTicket = 0;
    
            for(uint i = 0; i < tickets[_address].length;  i++) {
                ticketByAddress[numberOfTicket] = tickets[_address][i];
                numberOfTicket++;
            }
    
            return ticketByAddress; //don't work well in remix!
        }
    

    exemple of usage in a refund function:

    function makeRefund(uint256 _ticketId ) public returns(Ticket memory) {
            Ticket[] memory ticketByAddress = new Ticket[](tickets[msg.sender].length);
            Ticket memory refundTicket;
    
            uint numberOfTicket = 0;
    
            for(uint i = 0; i < tickets[msg.sender].length;  i++) {
                ticketByAddress[numberOfTicket] = tickets[msg.sender][i];
                numberOfTicket++;
            }
            ticketByAddress[_ticketId].refunded = true;
            refundTicket = ticketByAddress[_ticketId];
            
            if(refundTicket.categorie == 1){
                uint256 time = (dateEvent - refundTicket.date)/86400;
                require(time >= 1, "It is too late for a refund!");
                msg.sender.transfer(ticketPrice);
                
                maxTickets++;
                totalTicket++;
            }
    
            return refundTicket;
        }