Dean
Dean

Reputation: 678

Object with Array remove element behaviour

Here the question, I have an Object contain several elements in it

Example:

obj = {
    "0": { "a": "a1", "b": "b1"},
    "1": { "a": "a2", "b": "b2"}
};

And now, i wish to remove/delete the element 0, so it will be only element 1 left, but instead of the expected result of deleting element from an Object, i would like it act like an Array, the second element will replace the first element, with the example above, 1 will rename into 0 as well as all the element following onward.

Note: It may contain more than 2 element in the object, and is not necessary will remove the first element, it could be any element within the object

Here the solution i done so far,

var index = 0 //just for demo purpose

var tempArr = Object.keys(obj).map(function(key){
    return obj[key];
});

tempArr.splice(index,1);

obj = tempArr.reduce(function(acc, cur, i){
    acc[i] = cur;
    return acc;
}, {});

result:

obj = {
    "0": { "a": "a2", "b": "b2"}
}

This solution works and gave the result I want, but is there any better to do this?

Edited: As conclusion of the suggestion and discussion

Alternative way to solve the problem, which giving the almost identical result as my solution.

function Delete(index) {
    delete obj[index];
    var keys = Object.keys(obj);
    var update = false;
    for (var i = index + 1; i <= keys.length; i++) {
        obj[i - 1] = obj[i];
        update = true;
    }
    if (update) delete obj[keys[keys.length - 1]];
}

by @Anthony McGrath

delete obj[index];
obj = Object.keys(obj).reduce(function(newobj,key,i){
    newobj[i]=obj[key];
    return newobj;
},{});

by @Alexandru-Ionut Mihai

obj.length = Math.max.apply(null, Object.keys(obj))+1;
Array.prototype.splice.call(obj, index, 1);
delete obj.length; // optionally delete the length again

by @t.niese

Appreciated the helps once again.

Upvotes: 2

Views: 93

Answers (4)

Nina Scholz
Nina Scholz

Reputation: 386550

You could take all indices, which have to move and give it a new index/key. At the end delete the unwanted last object.

function deleteFromObject(object, index) {
    Object.keys(object).slice(index + 1).forEach(function (k) {
        object[index++] = object[k];
    });
    delete object[index];
}

var object = { 0: { a: "a1", b: "b1" }, 1: { a: "a2", b: "b2" }, 2: { a: "a3", b: "b3" }, 3: { a: "a4", b: "b4" } };

deleteFromObject(object, 0);
console.log(object);

deleteFromObject(object, 2);
console.log(object);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 0

Anthony McGrath
Anthony McGrath

Reputation: 802

How about this?

 obj = {
    "0": { "a": "a1", "b": "b1"},
    "1": { "a": "a2", "b": "b2"}
};

function Delete(p) {
    delete obj[p];
    var keys = Object.keys(obj);
    var update = false;
    for (var i = p + 1; i <= keys.length; i++) {
        obj[keys[i] - 1] = obj[keys[i]];
        update = true;
    }
    if (update)
        delete obj[keys[keys.length - 1]];
}

Delete(0); // delete first element

Upvotes: 1

Mihai Alexandru-Ionut
Mihai Alexandru-Ionut

Reputation: 48337

You can do it with only reduce method.

Also, use delete operator in order to delete one property from object

obj = {
    "0": { "a": "a1", "b": "b1"},
    "1": { "a": "a2", "b": "b2"}
};
delete obj['0'];
newobj=Object.keys(obj).reduce(function(newobj,key,i){
    newobj[i]=obj[key];
    return newobj;
},{});
console.log(newobj);

Upvotes: 1

t.niese
t.niese

Reputation: 40842

One thing you could do - if it has only numberic keys - is to convert it to an array like object by adding a length and then call splice on it.

obj = {
    "0": { "a": "a1", "b": "b1"},
    "1": { "a": "a2", "b": "b2"},
    "2": { "a": "a3", "b": "b3"},
    "3": { "a": "a4", "b": "b4"}
};

var index = 1;

obj.length = Math.max.apply(null, Object.keys(obj))+1;
Array.prototype.splice.call(obj, index, 1);
delete obj.length; // optionally delete the length again

console.dir(obj)

Upvotes: 1

Related Questions