0

I would like to know if it is possible to create a function that would return an array of structs for a specific condition. Let's consider this for the following contract:

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.9;

contract Trips {
    struct Trip {
        bytes20 id;
        address creator;
        uint256 createdAt;
        string destination;
    }

    Trip[] public tripsArray;
    
    function addTrip (string memory _destination) external {
        bytes20 id = bytes20(keccak256(abi.encodePacked(msg.sender, block.timestamp)));
        Trip memory trip = Trip({
            id: id,
            creator: msg.sender,
            createdAt: block.timestamp,
            destination: _destination
        });
        tripsArray.push(trip);
    }
}

How could I construct a function that would return an array of trips that a function caller address has created?

Edit:

I could think of the following solution however it is not ideal because it creates empty records in the array:

    function getTripsToAddress() public view returns (Trip[] memory) {
        Trip[] memory tripsForAddress = new Trip[](tripsArray.length);
          for (uint i = 0; i < tripsArray.length; i++) {
              if (tripsArray[i].creator == msg.sender) {
                  tripsForAddress[i] = tripsArray[i];
              }
              }
              return tripsForAddress;
    }

Thanks

2 Answers 2

0

One possible solution to your problem is to first initialize the array of trips that will be returned to have a length equal to the number of trips that were created by the function caller, and then iterate over the tripsArray to filter out the trips that were not created by the function caller.

Here is an example of how the getTripsToAddress function could be implemented:

function getTripsToAddress() public view returns (Trip[] memory) {
    // Count the number of trips that were created by the function caller
    uint count = 0;
    for (uint i = 0; i < tripsArray.length; i++) {
        if (tripsArray[i].creator == msg.sender) {
            count++;
        }
    }

    // Initialize the array of trips to return with the correct length
    Trip[] memory tripsForAddress = new Trip[](count);

    // Iterate over the tripsArray again, this time only adding the trips that were created by the function caller to the tripsForAddress array
    uint j = 0;
    for (uint i = 0; i < tripsArray.length; i++) {
        if (tripsArray[i].creator == msg.sender) {
            tripsForAddress[j] = tripsArray[i];
            j++;
        }
    }

    return tripsForAddress;
}

Note that this solution avoids creating empty records in the array, as it only initializes the tripsForAddress array with the correct length and adds only the trips that were created by the function caller to it.

0

try this:

function getArr() public view returns (Trip [] memory)
return tripsArray;
2
  • Thanks but this will return the entire array, while I only want to return records that a function caller address has created.
    – Przemo256
    Dec 4, 2022 at 20:24
  • To achieve that You need mapping
    – kapitankot
    Dec 4, 2022 at 20:31

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.