1

BEFORE YOU DOWNVOTE

I know questions on deleting mappings have come up thousands of times but I'd like to pose a question... can you delete it if it's in an array?

the following code allows the caller to delete a nested list of addresses

pragma solidity ^0.8.0;

contract Arrs {
    address[][] private _addy;

    constructor() {
        _addy.push();
        _addy[0].push();
    }

    function def() public {
        _addy[0][0] = msg.sender;
    }

    function del() public {
        delete _addy; // or _addy.pop()
        _addy.push();
        _addy[0].push();
    }

    function value() public view returns (address) {
        return (_addy[0][0]);
    }
}

running value() initially gives you the zero address, def() sets it to your address, del() resets it. It works great.

Now I KNOW that you cannot delete entire mapping arrays, however, I am not getting any errors or warnings in Remix/other IDEs and no errors or reverts when running the functions on a deployed contract on Goerli when I try and delete an array that contains the mapping.

contract Maps {
    mapping(uint256 => address)[] private _map;

    constructor() {
        _map.push();
    }

    function def() public {
        _map[0][0] = msg.sender;
    }

    function del() public {
        delete _map;
        _map.push();
    }

    function value() public view returns (address) {
        return (_map[0][0]);
    }
}

running value() initially gives you the zero address, def() sets it to your address, but del() is where it gets interesting.

In debugging on Remix, it seems that delete _map actually sets the _map array length to 0. However, when _map.push() is called, it somehow recovers the old mapping so when value() is called, is returns your address, not the 0 address.

I was wondering why this was and if there was a way to get around it or if I'll have to keep with the status quo and iterate through the mapping via a second array keeping track of the keys.

1 Answer 1

0

Hi Chainstack developer advocate here

Execelent observation. DL,DR: Delete doesn't really work as you think.

From Solidity's documentation:

delete a assigns the initial value for the type to a. I.e. for integers it is equivalent to a = 0, but it can also be used on arrays, where it assigns a dynamic array of length zero or a static array of the same length with all elements set to their initial value. delete a[x] deletes the item at index x of the array and leaves all other elements and the length of the array untouched. This especially means that it leaves a gap in the array. If you plan to remove items, a mapping is probably a better choice.

....

delete has no effect on mappings (as the keys of mappings may be arbitrary and are generally unknown). So if you delete a struct, it will reset all members that are not mappings and also recurse into the members unless they are mappings. However, individual keys and what they map to can be deleted: If a is a mapping, then delete a[x] will delete the value stored at x.

Hope that helps, happy coding!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.