For each user, I want to keep an array of holded assets (each asset has an ID).
My solution up until now is :
struct User {
uint userId;
uint[] assets;
}
For every asset
the user holds I push to the user's array the ID
of the asset
.
I want to give the user an option to delete an asset
.
What would be the most efficient approach to this?
Allocating all of the available assets
for every user (would be very wasterful given you have a lot of assets available) VS. iterating over all of his assets
everytime he'd like to delete an asset
, finding it in the array, then deleting it from it and shifting all of the array accordingly - also, the code for this is kinda hideous :
function deleteAsset(uint assetId) external returns(uint) {
bool assetFound = false;
// Check if the asset found is the last asset (or we go out of boundaries)
if (allUsers[msg.sender].assets[allUsers[msg.sender].assets.length - 1] == assetId){
assetFound = true;
}
else{
// Iterate over all user assets and find its index
for (uint i = 0; i < allUsers[msg.sender].assets.length - 1; i++) {
if (!assetFound && allUsers[msg.sender].assets[i] == assetId)
assetFound = true;
if(assetFound)
allUsers[msg.sender].assets[i] = allUsers[msg.sender].assets[i + 1];
}
}
if (assetFound){
delete allUsers[msg.sender].assets[allUsers[msg.sender].assets.length - 1];
allUsers[msg.sender].assets.length--;
}
}
Would be a lot easier if I could save a mapping
for each user indicating what asset does he have, but you can't return a mapping
from a function and I don't know the benchmarks of view
functions and "brute-forcing" all of the assets available for each user can take a plenty of time I assume.