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.