1

I was looking online to see various ways to delete a record from object and to replace the id of the record deleted by the next record available, meaning The usage of delete operator in JavaScript does not the delete the record id associated with it. say I have an Object:

obj= {
0:{},
1:{},
2:{},
3:{}
}

and I want to delete a record from that object, I do:

delete obj[1]

and it deletes the record but when I console.log(obj) I see:

obj= {
0:{},
2:{},
3:{}
}

I know one way could be to convert this object into an array, then delete the element from array and convert it back to an object. If I have to avoid all this conversion, is there a way in JavaScript object when we delete the record, the obj returns as the following when we delete the obj[1] record:

obj= {
    0:{},
    1:{},
    2:{}
    }

instead

obj= {
    0:{},
    2:{},
    3:{}
    }
Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
user1234
  • 3,000
  • 4
  • 50
  • 102
  • 4
    Objects do not have order. Why are you not using an array? – epascarello Oct 17 '18 at 23:12
  • @epascarello:that is how I get the data from server, I dont get it in array format – user1234 Oct 17 '18 at 23:13
  • Seems like a flaw and since objects do not have order, is no way to easily loop over the properties that come after the one you remove. So really your only option is to do some sort of looping conversion. – epascarello Oct 17 '18 at 23:15
  • Objects also don't have numeric keys. Your object might as well be `{ "0":{}, "1":{}, "2":{}, "3":{} }`. – Heretic Monkey Oct 17 '18 at 23:19
  • 3
    You should consider converting the data received from the server to an array immediately before doing any other work with it. You are currently trying to apply array like logic to something that cannot operate like an array. There literally is no difference between `0: {}` and `zero: {}` except the name of the key. The key name **is not an indexer**. – Claies Oct 17 '18 at 23:19
  • Possible duplicate of [Change position of JavaScript object key and data](https://stackoverflow.com/questions/44965155/change-position-of-javascript-object-key-and-data) – Heretic Monkey Oct 17 '18 at 23:25
  • @Claies: *"You are currently trying to apply array like logic to something that cannot operate like an array."* To be fair, arrays are objects too. So there is not such a big difference. But yes, if an object is to be treated like an array, it should be converted to one. – Felix Kling Oct 17 '18 at 23:37
  • @HereticMonkey: *"Objects also don't have numeric keys."* Neither have arrays (in JavaScript) ;) Although the term "numeric" is also used for strings that can be coerced to numbers. – Felix Kling Oct 17 '18 at 23:38
  • @FelixKling well, yes, I probably should have said something like "you are using an object that isn't iterable as if it were iterable" – Claies Oct 17 '18 at 23:40

5 Answers5

2

obj= {
  0:{a: 1},
  1:{b: 2},
  2:{c: 5},
  3:{d: 10}
}

const deleteElement = (index, obj) => {
    delete obj[index];
    return Object.keys(obj).reduce((agg, ele, i) => {
      agg[i] = obj[ele];
      return agg;
    }, {});
}

console.log(deleteElement(2, obj))
Tarek Essam
  • 3,602
  • 2
  • 12
  • 21
1

As mentioned before no. But a quick way to convert it could be

let Array=Object.keys(obj).map(x=>{
return obj[x]});
console.log(array);
Pari Baker
  • 696
  • 4
  • 19
1

Only way I can think about doing it without mapping to an array is to copy all the properties in the object down one and delete the last item.

var myObject = {
  0: {org: 0},
  1: {org: 1},
  2: {org: 2},
  3: {org: 3}
}


const removeIndex = (index, obj) => {
   var size = Object.keys(obj).length
   if (index<size-1) {
     for (let i = index; i<size-1; i++) {
       obj[i] = obj[i+1];       
     }
   }
   delete obj[size-1]   
}


removeIndex(1, myObject)
console.log(myObject)

But in reality, you should NOT be using an Object to act like an index on an Array. I would fix the server, if you can not do that, I would map it t an array when page loads and use it that way. If the server needs it back, map it back to this weird object.

If you have a large object, this deletion is going to take awhile, while in an array, it will be fast with splice.

epascarello
  • 204,599
  • 20
  • 195
  • 236
  • yea this wouldnt work for me, but as you suggested, mapping it to an array looks to be an ideal solution for me since I dont deal with server modifications. – user1234 Oct 17 '18 at 23:34
  • the object size could vary from length= 4 to length =20 or so, I'm sure if this could get cumbersome – user1234 Oct 18 '18 at 00:18
1

As the others have mentioned, you should be converting the object into an array. Here is another way to do it, via Array.from, and then let Array#splice take care of deletion and reindexing.

Adding a length property to the object makes Array.from treat the value as an array-like object and it also guarantees that the array is "in order".

var obj = {
  0:{0:0},
  1:{1:1},
  2:{2:2},
  3:{3:3}
};
obj.length = Object.keys(obj).length;
   
var arr = Array.from(obj);
arr.splice(1,1);
console.log(arr);

However, if you really need an object, because of how array methods work, you could apply Array#splice directly to the object, as long as it has a length property. The effect is that the object is mutated in place:

var obj = {
  0:{0:0},
  1:{1:1},
  2:{2:2},
  3:{3:3}
};
obj.length = Object.keys(obj).length;
   
Array.prototype.splice.call(obj, 1, 1);
console.log(obj);
// optionally: delete obj.length
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
0

Is there a way?

No automatically, you need to execute some logic (like the conversion you talked about).

Ele
  • 33,468
  • 7
  • 37
  • 75