In Solidity, a Mapping is a data structure that maps one piece of data to another piece of data. It is useful to think of a mapping as an X-Y table where the X column is one variable, and the Y column is another variable. Here are a few examples of a mapping:
//SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
contract mappings{
mapping(address => uint) public balances;
mapping(address => uint) public lastTxDate;
mapping(address => string) public nickname;
mapping(address => mapping(string => bool)) public favoriteColors;
}
One of the downfalls of mappings is that they are not iterable, which means you can not loop through them. A common solution around this drawback is to create an associated array that automatically increments with the key value of the mapping. I’ll show an example of this in a minute. Here’s an image that will help you visualize a mapping:
When you create a mapping, you must first decide what type of data the key is, and what type of data the value is.
The key can be any variable such as an integer, bytes, strings, or even an address.
The value can be any of these as well, including more complex reference-type variables like mappings or arrays. This means you can create nested mappings.
Nested Mappings
In the example above, we created a nested mapping, which means that the value column of the mapping included another mapping. This is somewhat hard to understand if you’re a novice developer, so I’ve created this image to make it a bit easier to understand:
Finally, here’s a contract you can run to tinker with to increase your understanding of nested mappings in Solidity.
//SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
contract nestedArrays{
mapping(address => mapping(string => bool)) public favoriteColors;
function getColors(address addressToCheck, string memory color) public view returns(bool){
return favoriteColors[addressToCheck][color];
}
function prefillColors() public{
favoriteColors[0x00000df178D3e15b2457948DA0474711B779C52E]["red"] = true;
favoriteColors[0x00000df178D3e15b2457948DA0474711B779C52E]["blue"] = true;
favoriteColors[0x00000df178D3e15b2457948DA0474711B779C52E]["yellow"] = false;
favoriteColors[0x000009D52d696B01f700dB5440a39d4A9F5aD392]["red"] = true;
favoriteColors[0x000009D52d696B01f700dB5440a39d4A9F5aD392]["blue"] = true;
favoriteColors[0x000009D52d696B01f700dB5440a39d4A9F5aD392]["orange"] = true;
favoriteColors[0x000016A1cF40b79AA9418DDdAdbd0DF02CdA4535]["green"] = true;
favoriteColors[0x000016A1cF40b79AA9418DDdAdbd0DF02CdA4535]["blue"] = true;
favoriteColors[0x000016A1cF40b79AA9418DDdAdbd0DF02CdA4535]["yellow"] = false;
}
}
How to Loop through a Mapping
When you want to iterate through a mapping, you must first create an associated array so that you can use to setup the for loop. Here is an example:
//SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
contract loopMapping{
mapping (string => uint) public namesMap;
string[] public namesArray;
function preFill() public{
namesMap["Tom"] = 0;
namesMap["Jerry"] = 0;
namesMap["Veronica"] = 1;
namesArray.push("Tom");
namesArray.push("Jerry");
namesArray.push("Veronica");
}
function getL() public view returns(uint){
return namesArray.length;
}
function sortVeronica() public view returns(bool){
bool VeronicaInList = false;
for(uint i = 0; i < namesArray.length; i++){
string memory getName = namesArray[i];
if(namesMap[getName] == 1){
VeronicaInList = true;
}
}
return VeronicaInList;
}
}