1

Once I do cancel some data from a struct, how do I remove the empty cells that I then create? Sorry for the silly question but I am just new :)

Below you will see "function removeAppointment" where, given a year, it cancels al the appointments that contain that year. I then remain with empty spaces in my struct that I would like to remove.

pragma solidity ^0.5.14;

contract Calendario_Appuntamenti {

    mapping (uint => calendar) public appointment;
    address owner;
    uint256 public _counter = 0;


    constructor ()public{
        owner = msg.sender;
    }

    modifier only0wner(){
        require (msg.sender == owner);
        _;
    }

    struct calendar{

        uint256 _id;
        uint256 _day;
        string _month;
        uint256 _year;
    }

    function addAppointment (uint256 _day, string memory _month, uint256 _year) public{
        _counter +=1;
        appointment [_counter] = calendar (_counter,_day,_month,_year); 
    }

    function removeAppointment (uint256 _yeartoremove) public only0wner {
        uint256 _i;
         _i = _counter;

        while (_i > 0){

            if(_yeartoremove == appointment [_i]._year){

                delete (appointment [_i]);
            }
            _i -=1;

        }
    }
}
2

To be more specific: you don't have "empty" spaces in your struct but in your mapping: you remove an entry from the mapping.

Typically a mapping doesn't have empty spaces: once you delete an entry from it the entry is just like any non-initialized entry: it simply doesn't exist. In your case you are (ab)using the mapping structure a bit by using it as an ordered list and therefore you can have "empty" entries.

You have basically a few options:

1) Reassign all the subsequent mapping entries to have a lower id. Quite expensive if you have lots of entries

2) Change your data structure to use an array instead of a mapping. This way you don't need a _counter variable either. When deleting you can shift subsequent elements - this is also expensive if you have many elements.

3) The best option: use a more sophisticated structures. Examples here (especially the last one might work for you): Are there well-solved and simple storage patterns for Solidity?

1
  • Thanks a lot for your help :) I will have a look! – Dani69654 Dec 12 '19 at 18:43
0

The short and direct answer is

delete myMapping[index];

That will create an initialized slow where the populated struct used to be.

That idea raises a concern about the "missing" I'd. Your loop implies an expectation that the IDs will be sequential.

Another concern is the use of a loop at all, because it won't scale. That's bad news. https://blog.b9lab.com/getting-loopy-with-solidity-1d51794622ad

Not enough is known about the application to be precise, but the idea is to organize data so you don't have to iterate.

For example, if there is only one entry for each year, month, day, then a key field could be a hash of those values. Then, you could use the CRUD pattern to enable delete.

If there is more than one entry per year, month, day, the structure would be a little more involved - just like data rules point to the right way to normalize a database (with different patterns).

Hope it helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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