eliminar objetos de la matriz por propiedad de objeto
var listToDelete = ['abc', 'efg'];
var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me
{id:'efg',name:'em'}, // delete me
{id:'hij',name:'ge'}] // all that should remain
¿Cómo elimino un objeto de la matriz haciendo coincidir la propiedad del objeto?
Solo JavaScript nativo, por favor.
Tengo problemas para usar el empalme porque la longitud disminuye con cada eliminación. Usar clonación y empalme en el índice original todavía te deja con el problema de disminuir la longitud.
¿ Supongo que usaste splice
algo como esto?
for (var i = 0; i < arrayOfObjects.length; i++) {
var obj = arrayOfObjects[i];
if (listToDelete.indexOf(obj.id) !== -1) {
arrayOfObjects.splice(i, 1);
}
}
Todo lo que necesita hacer para corregir el error es disminuirlo i
para la próxima vez, luego (y hacer un bucle hacia atrás también es una opción):
for (var i = 0; i < arrayOfObjects.length; i++) {
var obj = arrayOfObjects[i];
if (listToDelete.indexOf(obj.id) !== -1) {
arrayOfObjects.splice(i, 1);
i--;
}
}
Para evitar eliminaciones en tiempo lineal, puede escribir los elementos de la matriz que desea conservar sobre la matriz:
var end = 0;
for (var i = 0; i < arrayOfObjects.length; i++) {
var obj = arrayOfObjects[i];
if (listToDelete.indexOf(obj.id) === -1) {
arrayOfObjects[end++] = obj;
}
}
arrayOfObjects.length = end;
y para evitar búsquedas en tiempo lineal en un tiempo de ejecución moderno, puede utilizar un conjunto de hash:
const setToDelete = new Set(listToDelete);
let end = 0;
for (let i = 0; i < arrayOfObjects.length; i++) {
const obj = arrayOfObjects[i];
if (setToDelete.has(obj.id)) {
arrayOfObjects[end++] = obj;
}
}
arrayOfObjects.length = end;
que se puede resumir en una bonita función:
const filterInPlace = (array, predicate) => {
let end = 0;
for (let i = 0; i < array.length; i++) {
const obj = array[i];
if (predicate(obj)) {
array[end++] = obj;
}
}
array.length = end;
};
const toDelete = new Set(['abc', 'efg']);
const arrayOfObjects = [{id: 'abc', name: 'oh'},
{id: 'efg', name: 'em'},
{id: 'hij', name: 'ge'}];
filterInPlace(arrayOfObjects, obj => !toDelete.has(obj.id));
console.log(arrayOfObjects);
Si no necesita hacerlo en el lugar, eso es Array#filter
:
const toDelete = new Set(['abc', 'efg']);
const newArray = arrayOfObjects.filter(obj => !toDelete.has(obj.id));
Puede eliminar un elemento mediante una de sus propiedades sin utilizar bibliotecas de terceros como esta:
var removeIndex = array.map(item => item.id).indexOf("abc");
~removeIndex && array.splice(removeIndex, 1);