Created
September 28, 2022 15:42
-
-
Save horsefacts/6a228381c78c08b73cca34919ee14d6f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.13; | |
library Iterators { | |
// Function types: | |
// https://docs.soliditylang.org/en/latest/types.html#function-types | |
function map(uint256[] memory input, function (uint256) internal pure returns (uint256) f) | |
internal | |
pure | |
returns (uint256[] memory) | |
{ | |
uint256[] memory output = new uint256[](input.length); | |
for (uint256 i; i < input.length;) { | |
output[i] = f(input[i]); | |
unchecked { | |
++i; | |
} | |
} | |
return output; | |
} | |
function filter(uint256[] memory input, function (uint256) internal pure returns (bool) f) | |
internal | |
pure | |
returns (uint256[] memory) | |
{ | |
uint256 idx; | |
uint256[] memory filtered = new uint256[](input.length); | |
for (uint256 i; i < input.length;) { | |
if (f(input[i])) { | |
++idx; | |
filtered[idx] = input[i]; | |
} | |
unchecked { | |
++i; | |
} | |
} | |
uint256[] memory output = new uint256[](idx+1); | |
for (uint256 i; i < output.length;) { | |
output[i] = filtered[i]; | |
unchecked { ++i; } | |
} | |
return output; | |
} | |
function reduce(uint256[] memory input, function (uint256,uint256) internal pure returns (uint256) f) | |
internal | |
pure | |
returns (uint256) | |
{ | |
uint256 acc; | |
for (uint256 i; i < input.length;) { | |
acc = f(acc, input[i]); | |
unchecked { | |
++i; | |
} | |
} | |
return acc; | |
} | |
} | |
// Free functions: | |
// https://docs.soliditylang.org/en/latest/contracts.html#functions | |
function addOne(uint256 n) pure returns (uint256) { | |
return n + 1; | |
} | |
function isOdd(uint256 n) pure returns (bool) { | |
return n % 2 == 1; | |
} | |
function add(uint256 acc, uint256 n) pure returns (uint256) { | |
return acc + n; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: UNLICENSED | |
pragma solidity ^0.8.13; | |
import {Iterators, addOne, isOdd, add} from "../src/Iterators.sol"; | |
import "forge-std/Test.sol"; | |
contract IteratorsTest is Test { | |
// Using For: | |
// https://docs.soliditylang.org/en/latest/contracts.html#using-for | |
using Iterators for uint256[]; | |
uint256[] input; | |
function setUp() public { | |
// Create a uint256 array containing 0..10 | |
input = new uint256[](10); | |
for (uint256 i; i < input.length; i++) { | |
input[i] = i; | |
} | |
} | |
function test_chained_functions() public { | |
uint256 sum = input.map(addOne).filter(isOdd).reduce(add); | |
assertEq(sum, 25); | |
} | |
function test_map() public { | |
uint256[] memory mapped = Iterators.map(input, addOne); | |
assertEq(mapped[0], 1); | |
assertEq(mapped[1], 2); | |
assertEq(mapped[2], 3); | |
assertEq(mapped[3], 4); | |
assertEq(mapped[4], 5); | |
assertEq(mapped[5], 6); | |
assertEq(mapped[6], 7); | |
assertEq(mapped[7], 8); | |
assertEq(mapped[8], 9); | |
assertEq(mapped[9], 10); | |
} | |
function test_filter() public { | |
uint256[] memory filtered = Iterators.filter(input, isOdd); | |
assertEq(filtered.length, 6); | |
assertEq(filtered[0], 0); | |
assertEq(filtered[1], 1); | |
assertEq(filtered[2], 3); | |
assertEq(filtered[3], 5); | |
assertEq(filtered[4], 7); | |
assertEq(filtered[5], 9); | |
} | |
function test_reduce() public { | |
uint256 reduced = Iterators.reduce(input, add); | |
assertEq(reduced, 45); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment