0

I written a contract that has one to many relationship elements. Each id holds different names(Eg: id = 1 holds name a,b and c). I need to delete name 'a' from id = 1.

struct IdStruct{
    bytes12[] structArray; 
}

mapping(string => IdStruct) idStructs;

function appendNames(string id, bytes12 name) payable returns (bool success){ 
 idStructs[id].structArray.push(name); 
} 

function getName(string id) returns(bytes12[]){ 
  return idStructs[id].structArray; 
}

I tried delete idStructs[id].structArray[name]; but nothing is deleted and when I try delete idStructs[id].structArray;, it deletes all names under id=1.

2

I guess your calling delete idStructs[id].structArray. That means it will delete all the elements in an array. If you want to delete particular element, you need to loop through all the elements in that array. If element is matching then you need to delete that element.

Find below sample code:

function deleteElement(string id, bytes12 name){
    for(uint index=0;index<idStructs[id].structArray.length;index++){
        if(idStructs[id].structArray[index]==name){
            delete idStructs[id].structArray[index];
            break;
        }
    }
}
| improve this answer | |
  • Thanks, It works...but the value is turned into null. Even if I delete idStructs[id].structArray[0] , structArray[0] still exists as null and it returns 0x0000000000000000000000000000000000000000 – angelmaria Feb 19 '18 at 11:39
  • 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 reset. For structs, it assigns a struct with all members reset. solidity.readthedocs.io/en/latest/… – Jitendra Kumar. Balla Feb 19 '18 at 12:01
1

This is because delete idStructs[id].structArray[name] is trying to delete the bytes12 item at index name, which is incorrect. What you want to do here is delete the item at it's index from 0. Here's one solution to this:

struct IdStruct {
    bytes12[] structArray; 
}

mapping(string => IdStruct) idStructs;

function appendNames(string id, bytes12 name) payable returns (bool success, uint index){ 
    idStructs[id].structArray.push(name); 
    return (true, idStructs[id].structArray.length-1);
} 

function getName(string id) returns(bytes12[]){ 
    return idStructs[id].structArray; 
}

function deleteName(string id, bytes12 name){
    for(uint index = 0;index<idStructs[id].structArray.length;index++){
        if(idStructs[id].structArray[index]==name){
            delete idStructs[id].structArray[index];
            break;//Don't break here if it might be in the array more than once
        }
    }
}

Alternatively, you can have the user supply the index they want to delete by having a function that gets the index of the value. You can also have them supply the name and the id to deleteName and verify that it is what they want to delete.

| improve this answer | |

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.