Consider the following solidity function:
function example(uint256[] calldata _numbers) external {
uint256[] memory _evenNumbers;
// initialize `_evenNumbers` and populate it with even numbers from the `_numbers` array
someOtherFunction(_evenNumbers);
}
_numbers
is a uint256
array containing an unspecified amount of even and odd numbers. someOtherFunction
expects an array of even numbers, what's the best way to initialize and populate _evenNumbers
with all even numbers from the _numbers
array?
The simplest solution would be something like this:
function example(uint256[] calldata _numbers) external {
uint256[] memory _evenNumbers = new uint256[](_numbers.length);
// initialize _evenNumbers and populate it with even numbers from the _numbers array
uint256 _evenCounter;
for (uint256 i; i < _numbers.length; ++i) {
if (_numbers[i] % 2 == 0) {
_evenNumbers[_evenCounter] = _numbers[i];
++_evenCounter;
}
}
someOtherFunction(_evenNumbers);
}
This unfortunately doesn't work as _evenNumbers
would contain as many trailing zeros as the amount of odd numbers in the original _numbers
array, which would be considered valid even numbers.
A way around that would be the following inline assembly code:
assembly {
mstore(_evenNumbers, _evenCounter)
}
This works and is probably the most gas efficient way to do it but I don't think that using inline assembly can be considered a best practice, but the only other solution I can think of is count the even numbers with a for
loop first and then populate _evenNumbers
with a second for
loop, which is very ugly and inefficient.