I have an array of addresses and a function which returns how many times an address is in the array. For example, if the array has ['0x00', '0x01', '0x00'] the function will return 2 for 0x00 and 1 for 0x01
I would like to know if my approach is efficient enough to work with a large number of addresses
address[] public users;
function userCounter(address user) public view returns(uint){
uint counter;
for(uint i; i<users.length; i++){
if(users[i] == user){
counter++;
}
}
return counter;
}
Any idea how I could improve it? Currently it takes a while to iterate over 300 elements so I imagine how bad it's going to be for a larger number.
Best Answer
You might be interested in using two storage structures for your scenario.
A mapping which can hold the key + value of
address
+count
, and an array which holds the unique list of addresses which can be iterated on.You mention a payable function which creates the original list of users through a payment. Here is an example of how that could be written to support these types:
In this case, whenever a brand new user donates .002 ETH, they get added to the
users
array. Otherwise, we simply increment on the mapping which tracks the count of donations per user.Then your
userCounter
function simply becomes a read on thecount
mapping: