0

I want to delete a object on my objects array, but i cant find a better way than using some loop to do such a thing, on each object we have an ID

example:

var array = [{
    id         : String,
    price      : Number,
    someOtherVars : String
}] 

var element = {
    id         : "00dks",//this is a unic value
    price      : 12,
    someOtherVars : "some value"    
}

var element2 = {
    id         : "a43sdk",
    price      : 30,
    someOtherVars : "some value"    
}

var element3 = {
    id         : "0as0d",
    price      : 122,
    someOtherVars : "some value"    
}
array.push(element);
array.push(element2);
array.push(element3);

so... what is the most efficient way of doing this?

ps: i'm looking for a way to access the element by the key with out using any kind of loop, like the function .find(), example array["0as0d"], to get element3

  • 1
    Possible duplicate of [Deleting array elements in JavaScript - delete vs splice](http://stackoverflow.com/questions/500606/deleting-array-elements-in-javascript-delete-vs-splice) – Rajesh Sep 11 '16 at 04:40
  • You can use array.splice – Robert Sep 11 '16 at 04:41
  • I'm looking for a answer that doesn't loop the array – Giuan Adauto Sep 11 '16 at 04:52
  • @GiuanAdauto the only way to do this without looping is to track elem id's to indexes in the array. For instance, you could create an object `var o = { "00dks": 0, "a43sdk": 1, "0as0d": 2 }`, then you could delete like this: `array.splice(o["0as0d"], 1)` – Adam Sep 11 '16 at 04:56
  • @GiuanAdauto You will have to loop over array to find where element exists, so that you can delete it. – Rajesh Sep 11 '16 at 04:56
  • Your requirement to not loop the array suggests using a `Map` or object to store your data. – jdphenix Sep 11 '16 at 05:03
  • Can you update your question with an idea of how big your data actually is? – jdphenix Sep 11 '16 at 05:30

3 Answers3

2

Don't use an array, but a Map.

var map = new Map();

var element = {
    id         : "00dks",//this is a unic value
    price      : 12,
    someOtherVars : "some value"    
}

var element2 = {
    id         : "a43sdk",
    price      : 30,
    someOtherVars : "some value"    
}

var element3 = {
    id         : "0as0d",
    price      : 122,
    someOtherVars : "some value"    
}
map.set(element.id, element);
map.set(element2.id, element2);
map.set(element3.id, element3);

// later... 

if (map.delete("0as0d")) {
  console.log('delete successful');
}

console.log(map.size);
jdphenix
  • 15,022
  • 3
  • 41
  • 74
1

I do a findIndex followed by splice.

const index = array.findIndex(a => a.id === id);
if (index !== -1) {
   array.splice(index, 1);
}

To avoid looping, store the array as an object:

const map = {};
map[element1.id] = element1;
map[element2.id] = element2;
map[element3.id] = element3;

to retrieve the element, use

const element = map[whateverId];

To delete the element, use

delete map[whateverId];

To loop through the map, use:

for (var key in map) {
  var value = map[key];
  // do some stuff
}
vijayst
  • 20,359
  • 18
  • 69
  • 113
  • Just be aware that `.findIndex()` is not supported in IE. It is in current browsers. – jfriend00 Sep 11 '16 at 04:44
  • does this function loops the array to find the element? – Giuan Adauto Sep 11 '16 at 04:47
  • yes, it loops the elements. if you want es5 code, you could use one of lodash or underscore, which has similar methods. – vijayst Sep 11 '16 at 04:50
  • I'm looking for a answer that doesn't loop the array – Giuan Adauto Sep 11 '16 at 04:51
  • to avoid looping, you should store it as an object. In that way, you could retrieve the object with the key. – vijayst Sep 11 '16 at 04:56
  • Why do you want to avoid looping @GiuanAdauto? – Rajesh Sep 11 '16 at 04:58
  • @Rajesh, Its gonna be a huge array, I need efficiency – Giuan Adauto Sep 11 '16 at 05:26
  • i need a array, if its possible – Giuan Adauto Sep 11 '16 at 05:26
  • @GiuanAdauto point is you will search array based on keys inside object. Keeping map is an alternative but then it will add load to maintain both variables in sync. Also even if you have an array of 100000, it will not take much to search index. [Sample Fiddle](https://jsfiddle.net/RajeshDixit/v1t2rnqr/1/). – Rajesh Sep 11 '16 at 05:34
  • it is not possible to delete an item in an array without looping through it. storing it as property / value pairs in an object is the only way to delete without looping. You could delete using `delete map.propertyName;` To loop through the map, you could use `for (propertyName in map) { object = map[propertyName]; }` – vijayst Sep 11 '16 at 06:08
1

You cannot access an array in the manner you request: array["0as0d"], because it is indexed by an integer, not a string. If you want to reference in that manner you will need to store your objects in another object, keyed off of id:

var asObject = array.reduce(function(obj, cur) {
  obj[cur.id] = cur;
  return obj;
}, {});

console.log(asObject["0as0d"]);
// to remove this item:
delete asObject["0as0d"];

You can use Array.filter to remove the item from your array:

var element = {
    id         : "00dks",//this is a unic value
    price      : 12,
    someOtherVars : "some value"    
}

var element2 = {
    id         : "a43sdk",
    price      : 30,
    someOtherVars : "some value"    
}

var element3 = {
    id         : "0as0d",
    price      : 122,
    someOtherVars : "some value"    
}

var array = [];
array.push(element);
array.push(element2);
array.push(element3);

var id = '0as0d';
var filtered = array.filter(function(item) {
  return item.id !== id;
});

console.log(filtered);
Rob M.
  • 35,491
  • 6
  • 51
  • 50
  • I'm looking for a answer that doesn't loop the array – Giuan Adauto Sep 11 '16 at 04:50
  • 1
    I only skimmed your answer at first, completely breezing over your implementation using an object to avoid looping. The only answer to this really is "use an appropriate data structure for your requirements" – jdphenix Sep 11 '16 at 05:23
  • @jdphenix, what data structure do you think is the best to do so? – Giuan Adauto Sep 11 '16 at 05:28
  • A map. JavaScript has implementations with the performance characteristics you're looking for with objects as hashmaps (i.e. @RobM.'s answer),. or using an ES6 `Map` (my answer). – jdphenix Sep 11 '16 at 05:29