How to iterate a mapping of strings

mappingsolidity

Here is my code:

contract MappingsC {
    mapping(string => uint) public person;
    
    function addPerson() external {
        person["Jhon"] = 34;
        person["Doe"] = 11;
    }
    
    function getPersonAge(string calldata name) view external returns(uint) {
        return person[name];
    }
    
    function getAllPerson()  view external returns(uint[] memory) {
        uint[] memory entries = new uint[](2);
        for (uint i = 0; i < 2; i++) {
            entries[i] = person[i];
        }
    }
    
}

It gives the following error:

contracts/Mappings.sol:18:33: TypeError: Type uint256 is not implicitly convertible to expected type string memory.
entries[i] = person[i];
^

Best Answer

What you're doing wrong is that on line 18 you're trying to use a uint256 key, while the correct usage would be to use a key of type string to be access the mapped value.

A mapping doesn't keep track of what keys were assigned. As a workaround, you could define an array to keep track of all the keys:

string[] personeNames;

Then, you would push a new name to it every time you add a new person, as follows:

function addPerson() external {
    person["Jhon"] = 34;
    personeNames.push("Jhon");
    person["Doe"] = 11;
    personeNames.push("Doe");
}

The final step would be to integrate inside the getter function, as follows:

function getAllPerson()  view external returns(uint[] memory entries) {
    entries = new uint[](personeNames.length);
    for (uint i = 0; i < personeNames.length; i++) {
        entries[i] = person[personeNames[i]];
    }
}
Related Topic