1

I have the following array of numbers:

1. [2, 4, 6, 8]

2. [4, 2, 5, 7]

I need to check whether or not each number of the first array is included in the second array. In that case, a function needs to return true. If at least one number of the first array is not included in the second array, the function needs to return false.

I can do this by comparing each pairs of numbers, but that doesn't seem the most computationally efficient function. What would be the most gas-efficient way to achieve this in Solidity?

UPD: The first array numbers are function inputs, the second array numbers are global variables.

4
  • 2
    Are these global (state-variable) arrays, or local (function argument) arrays? If they're global, then most likely the method that you've mentioned would be the cheapest, as the other option - sorting each one of the arrays - would be computationally faster (O(n*log n) instead of O(n^2)), but requires changing state variables, which would ultimately consume a lot of gas. Oct 14, 2018 at 12:39
  • Thank you, I should have clarified that. The first array numbers are function inputs, the second array numbers are global variables.
    – Ruham
    Oct 14, 2018 at 12:42
  • Do you need the result to be written back to the state data, or are you just returning it to the caller? Oct 14, 2018 at 17:25
  • I need to return "true" or "false".
    – Ruham
    Oct 14, 2018 at 19:08

3 Answers 3

2

Simply get the first number from the input array and check it against the second array numbers, from first to fourth, if you do not find it, break and return false. If you find it, break and pass to the second of the first array.

When you finished numbers in the first array and any number of the first array map to some of the second, you can return true.

It can be demonstrated that this is the more efficient way to check them against your constraints.

Hope this helps!

0

If you can, maintain a mapping for the global array?

mapping (uint => bool) exists

Then the check would simply be looping through the function arg array.

0

This is an implementation example from @RickPark answer, using each steps in its response as comments.

function hardcodedExample() public pure returns(bool) {
    uint256[4] memory first = [uint256(2), 4, 6, 8];
    uint256[4] memory second = [uint256(4), 2, 5, 7];

    // Simply get (start from) the first number from the input array 
    for (uint256 ii = 0; ii < first.length; ii++) {
        // and check it against the second array numbers, from first to fourth,
        for (uint256 jj = 0; jj < second.length; jj++) {
            // If you find it
            if (first[ii] == second[jj]) {
                // break and pass to the second of the first array
                break; 

            // if you do not find it
            } else {
                // and you were checking the fourth number of the second array
                // (meaning you have checked them all)
                // break and return false
                if (jj == second.length - 1) return false;

                // otherwise check the next number in the second array
                continue;
            }
        }
    }

    // When you finished (checking each) number in the first array,
    // and any number of the first array map to some of the second array, 
    // you can return true.
    return true;
}

As a full contract example, based on the scenario given in the updated question:

  • The first array numbers are function inputs
  • the second array numbers are global (state) variables.
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

contract Arrays {

    uint256[4] stored = [uint256(4), 2, 5, 7];

    function areNumbersInStorage(uint256[] memory _input) public view returns(bool) {

        // Simply get (start from) the first number from the input array 
        for (uint256 ii = 0; ii < _input.length; ii++) {
            // and check it against the numbers (in storage), from first to fourth,
            for (uint256 jj = 0; jj < stored.length; jj++) {
                // If you find it
                if (_input[ii] == stored[jj]) {
                    // break and pass to the second number in the storage array
                    break; 

                // if you do not find it
                } else {
                    // and you were checking the fourth (last) number of the storage array
                    // (meaning you have checked them all)
                    // break and return false
                    if (jj == stored.length - 1) return false;

                    // otherwise check the next number in the storage array
                    continue;
                }
            }
        }
        
        // When you finished looping through all the input numbers,
        // and any number of the input array maps to some numbers in the storage array, 
        // you can return true.
        return true;

    }

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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