2

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.

1 Answer 1

1

I think the most gas-efficient way is moving the check condition into someOtherFunction() and processing the whole array.

3
  • My bad, I should've specified that this is just a very simple hypothetical and someOtherFunction is meant to be an external function we have no control over
    – Sam
    Mar 8 at 15:34
  • I see. In this case, Array.slice(docs.soliditylang.org/en/v0.6.0/types.html#array-slices) should be the most efficient solidity method AFAIK. Mar 9 at 2:14
  • Unfortunately array slices are only implemented for calldata arrays as of solidity 0.8.x
    – Sam
    Mar 10 at 11:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.