I understand this:
I want to have mappings with addresses as keys and structs as the value. I want to store these addresses in an array and iterate through them. so far it looks like this how would I modify this?
but I don't see what this has to do with it:
Can you have an array of mappings?
No. You can put a mapping in a struct, however, and you can make arrays and mappings of those structs, so you should be able to work it out using struct
to negotiate between the mapping and the limitations of arrays.
Is your question about merging the mapping and the array into a more concise form? What you're doing is a good start if you need random access to the structs as well as the ability to enumerate the keys. If either of those concerns is not a real requirement, then you might save a little gas and get by with just a mapping or just an array. Otherwise, you need both because they address different requirements.
As a PSA, there is a problem unless you are certain there will never be too many users to fetch them all before running out of gas. Keep in mind that if it runs out of gas, or hits the block gasLimit, the user gets nothing. So, it is a potentially fatal issue.
returns (address[])
If you can't be 100% sure that is not the case, then go for efficiency.
function userCount() public view returns(uint) {
return userAddresses.length;
}
function getUserAtIndex(uint row) public view returns(address) {
return userAddresses[row];
}
That approach ensures it will always be possible to fetch the list. It will also be more efficient because it affords the client the possibility of only fetching new information, as needed, instead of always fetching the works, which is a lot of work.
As a general habit, I prefer the latter approach than the former, especially in early formative stages because it works reliably. Toward the end when looking for ways to optimize you might consider (carefully) if return(address[])
is safe in this case (and why) and you might also include both options so there is something to fall back on if the big bang approach falters for some unexpected reason.
It might be worth mentioning that it is perfectly safe to pass arrays around with internal
and private
functions because only storage pointers (basically, a storage offset) are passed. Not the data. You see it a lot in examples you might be following. For a public
function, it implies data equal to the total stored contents of the array, so potentially huge.
Hope it helps.