I need to loop over an array (anti-pattern, I know) and delete elements if they satisfy a condition.
function withdraw(uint256 amount) external {
WithdrawalRequest[] storage requests = withdrawalRequests[msg.sender];
for (uint i=0; i < requests.length; i++) {
// See below for the error this line throws
if (bytes(requests[i]).length == 0) { continue }
if (block.timestamp >= requests[i].withdrawableAt) {
// do some stuff...
// Best approach?
delete requests[i];
}
}
// do some more stuff...
}
Per this answer on removing array elements, it seems like the "Delete and Leave Gaps" would be my best approach, since I don't have to mutate the array length in the middle of the loop by moving the current element to the end and chopping it. I'd just have to check the number of bytes of requests[i]:
if (bytes(requests[i]).length == 0) { continue }
But that's also throwing me the error TypeError: Explicit type conversion not allowed from "struct Contract.WithdrawalRequest storage ref" to "bytes storage pointer".
How would you recommend removing an array element in a for loop?
i(your loop counter) by 1, but you should be careful with this approach, because wheni == 0, it will becomemax uint256, and then your loop will exit. So you should probably think of a different approach. There's a general solution for this type of problems, which combines the use of a mapping and an array. There are several such answers on this website, including some of my own, for example, here. – goodvibration May 15 '20 at 10:36