Skip to content

Instantly share code, notes, and snippets.

@lyhistory
Created January 30, 2019 08:18
Show Gist options
  • Save lyhistory/259283f6d6bc078c1accfa2d74ce02dc to your computer and use it in GitHub Desktop.
Save lyhistory/259283f6d6bc078c1accfa2d74ce02dc to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.5.1+commit.c8a2cb62.js&optimize=false&gist=
pragma solidity >=0.4.0 <0.6.0;
/// @dev Models a uint -> uint mapping where it is possible to iterate over all keys.
library IterableMapping
{
struct itmap
{
mapping(uint => IndexValue) data;
KeyFlag[] keys;
uint size;
}
struct IndexValue { uint keyIndex; uint value; }
struct KeyFlag { uint key; bool deleted; }
function insert(itmap storage self, uint key, uint value) returns (bool replaced)
{
uint keyIndex = self.data[key].keyIndex;
self.data[key].value = value;
if (keyIndex > 0)
return true;
else
{
keyIndex = self.keys.length++;
self.data[key].keyIndex = keyIndex + 1;
self.keys[keyIndex].key = key;
self.size++;
return false;
}
}
function remove(itmap storage self, uint key) returns (bool success)
{
uint keyIndex = self.data[key].keyIndex;
if (keyIndex == 0)
return false;
delete self.data[key];
self.keys[keyIndex - 1].deleted = true;
self.size --;
}
function contains(itmap storage self, uint key) returns (bool)
{
return self.data[key].keyIndex > 0;
}
function iterate_start(itmap storage self) returns (uint keyIndex)
{
return iterate_next(self, uint(-1));
}
function iterate_valid(itmap storage self, uint keyIndex) returns (bool)
{
return keyIndex < self.keys.length;
}
function iterate_next(itmap storage self, uint keyIndex) returns (uint r_keyIndex)
{
keyIndex++;
while (keyIndex < self.keys.length && self.keys[keyIndex].deleted)
keyIndex++;
return keyIndex;
}
function iterate_get(itmap storage self, uint keyIndex) returns (uint key, uint value)
{
key = self.keys[keyIndex].key;
value = self.data[key].value;
}
}
// How to use it:
contract User
{
// Just a struct holding our data.
IterableMapping.itmap data;
// Insert something
function insert(uint k, uint v) returns (uint size)
{
// Actually calls itmap_impl.insert, auto-supplying the first parameter for us.
IterableMapping.insert(data, k, v);
// We can still access members of the struct - but we should take care not to mess with them.
return data.size;
}
// Computes the sum of all stored data.
function sum() returns (uint s)
{
for (var i = IterableMapping.iterate_start(data); IterableMapping.iterate_valid(data, i); i = IterableMapping.iterate_next(data, i))
{
var (key, value) = IterableMapping.iterate_get(data, i);
s += value;
}
}
}
pragma solidity >=0.4.0 <0.6.0;
contract MappingExample {
mapping(address => uint) public balances;
function update(uint newBalance) public {
balances[msg.sender] = newBalance;
}
}
contract MappingUser {
function f() public returns(uint){
MappingExample m = new MappingExample();
m.update(100);
return m.balances(address(this));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment