0

Suppose I have a struct as follows:

struct Item {
    uint groupId;
    uint itemId;
    // more data here
}

Each groupId is unique. Each itemId is unique only to the given group. So, each Item is only uniquely defined by the combination (tuple) of groupId and itemId.

Now I want to have a mapping that lets me do a couple of things:

  1. I want to retrieve an item based on groupId and itemId.
  2. I want to get all items for a given groupId.

If in my contract, i have this:

mapping(uint => (mapping(uint => Item)) items

then I can easily get a given Item:

item = items[groupId][itemId];

But how can I get a list/array of all items for a given groupId?

0

Instead of a nested mapping, you could nest a storage array inside a mapping as follows:

// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

contract MappingsC {
    struct Item {
        uint groupId;
        uint itemId;
    }
    
    mapping(uint => Item[]) private items;
    
    function setItem(uint groupId, uint itemId) public {
        items[groupId].push(Item(groupId, itemId));
    }

    function getItem(uint groupId, uint itemId) public view returns (Item memory) {
        return items[groupId][itemId];
    }
    
    function getItems(uint groupId) public view returns (Item[] memory) {
        return items[groupId];
    }

}

That way, you could return each item individually by passing in a groupId and a itemId to getItem(...), and still be able to return an entire nested storage array just by passing in a groupId to getItems(...). This works as arrays are iterable, unlike mappings.

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.