Explore techniques to filter an array.
ArrayDemo.sol
containing a contract
called ArrayDemo
. Initialize an array containing the numbers from 1 to 10. Add a stub for a function called getEvenNumbers
that returns a uint[] memory
.
memory
array to hold the results, but to do so, we need to know how big to make the array. Don’t be tempted to count the number of evens in numbers
, as what happens if we modify it later?
The simple and obvious solution is to simply iterate through numbers
and count how many even numbers are present. You could add that functionality in getEvenNumbers()
, but it might be useful elsewhere, so a better practice would be to separate these concerns into another function.
Go ahead and write it on your own. It needs to:
uint
to hold the resultsnumbers
and increment that number if the value is evenReveal code
_
in front of the function name is a practice used by some developers, in Solidity and in other languages, to indicate visually that this function is intended for internal use only.
getEvenNumbers()
, we can simply loop through numbers
, and add the even numbers to the array to be returned.
Finish the function on your own. It needs to:
numbers
array and if a given number is even, add it to the next unused index in the results arrayReveal code
view
? You aren’t modifying state, so you should mark it as such.
[2,4,6,8,10]
. The total gas cost will be about 63,947, depending on if you used the same helper variables, etc.
numEven
, and initialize it with 5, the number of even numbers in the array. Modify getEvenNumbers()
to use numEven
instead of the _countEvenNumbers()
function. It should now look like:
Reveal code
numEven
each time the array adds an even number.
numbers
and numEven
so that they have their respective default values to begin with.
debugLoadArray
that takes a uint
called _number
as an argument, and fills the array by looping through _number
times, pushing each number into the array. For now, don’t update numEven
.
Reveal code
numEven
when the number added is even. We can’t just calculate it, because although the numbers are sequential in the debug function, they might not be in real world use.
Reveal code
_countEvenNumbers()
.
if
statement in debugLoadArray
that checks for even numbers and load 500 numbers. The Remix EVM should be able to handle this, but it might hang up for a moment, or even crash. (You can also do this experiment with 250 numbers instead.)
numEven
. You should get about 11,536,282, or an increase of about 213,150 gas.
Now, test out getEvenNumbers()
using numEven
vs. using _countEvenNumbers()
. With numEven
, it should cost about 1,578,741 gas to find the even numbers. Using _countEvenNumbers()
, that cost increases to 1,995,579 gas, an increase of 416,838 gas.
_numEven
results in a savings of over 400k gas when filtering for even numbers. Even better, you might realize that the upfront cost difference will be spread across all of your users over time, making them almost trivial. You also might think that it’s possible that the filter function could be called dozens of times for each time 500 numbers are loaded.
These are all valid considerations that you should evaluate as you are developing your code solution to a business problem. One last critical element to consider is that there is only a gas cost to read from the blockchain if it’s another contract calling the function. It doesn’t cost any gas to call view
or pure
functions from a front end or app.
If getEvenNumbers
will never be called by another contract, then using numEven
might cost more for no benefit!