mirror of
https://github.com/autistic-symposium/web3-starter-sol.git
synced 2025-07-22 06:38:57 -04:00
86 lines
2.2 KiB
Solidity
86 lines
2.2 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.17;
|
|
|
|
// You cannot iterate through a mapping.
|
|
// So here is an example of how to create an iterable mapping.
|
|
|
|
|
|
|
|
library IterableMapping {
|
|
// Iterable mapping from address to uint;
|
|
struct Map {
|
|
address[] keys;
|
|
mapping(address => uint) values;
|
|
mapping(address => uint) indexOf;
|
|
mapping(address => bool) inserted;
|
|
}
|
|
|
|
function get(Map storage map, address key) public view returns (uint) {
|
|
return map.values[key];
|
|
}
|
|
|
|
function getKeyAtIndex(Map storage map, uint index) public view returns (address) {
|
|
return map.keys[index];
|
|
}
|
|
|
|
function size(Map storage map) public view returns (uint) {
|
|
return map.keys.length;
|
|
}
|
|
|
|
function set(Map storage map, address key, uint val) public {
|
|
if (map.inserted[key]) {
|
|
map.values[key] = val;
|
|
} else {
|
|
map.inserted[key] = true;
|
|
map.values[key] = val;
|
|
map.indexOf[key] = map.keys.length;
|
|
map.keys.push(key);
|
|
}
|
|
}
|
|
|
|
function remove(Map storage map, address key) public {
|
|
if (!map.inserted[key]) {
|
|
return;
|
|
}
|
|
|
|
delete map.inserted[key];
|
|
delete map.values[key];
|
|
|
|
uint index = map.indexOf[key];
|
|
address lastKey = map.keys[map.keys.length - 1];
|
|
|
|
map.indexOf[lastKey] = index;
|
|
delete map.indexOf[key];
|
|
|
|
map.keys[index] = lastKey;
|
|
map.keys.pop();
|
|
}
|
|
}
|
|
|
|
contract TestIterableMap {
|
|
using IterableMapping for IterableMapping.Map;
|
|
|
|
IterableMapping.Map private map;
|
|
|
|
function testIterableMap() public {
|
|
map.set(address(0), 0);
|
|
map.set(address(1), 100);
|
|
map.set(address(2), 200); // insert
|
|
map.set(address(2), 200); // update
|
|
map.set(address(3), 300);
|
|
|
|
for (uint i = 0; i < map.size(); i++) {
|
|
address key = map.getKeyAtIndex(i);
|
|
|
|
assert(map.get(key) == i * 100);
|
|
}
|
|
|
|
map.remove(address(1));
|
|
|
|
// keys = [address(0), address(3), address(2)]
|
|
assert(map.size() == 3);
|
|
assert(map.getKeyAtIndex(0) == address(0));
|
|
assert(map.getKeyAtIndex(1) == address(3));
|
|
assert(map.getKeyAtIndex(2) == address(2));
|
|
}
|
|
}
|