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
Comment supprimer un objet du tableau en faisant correspondre la propriété de l'objet?
Seul JavaScript natif s'il vous plaît.
Je ne parviens pas à utiliser l'épissure car la longueur diminue à chaque suppression . L'utilisation de clones et d'épissures sur l'index d'origine vous laisse toujours le problème de la diminution de la longueur.
Je suppose que vous avez utilisé splice
quelque chose comme ceci?
for (var i = 0; i < arrayOfObjects.length; i++) {
var obj = arrayOfObjects[i];
if (listToDelete.indexOf(obj.id) !== -1) {
arrayOfObjects.splice(i, 1);
}
}
Tout ce que vous devez faire pour corriger le bogue est de décrémenter i
pour la prochaine fois, puis (et une boucle en arrière est aussi une option):
for (var i = 0; i < arrayOfObjects.length; i++) {
var obj = arrayOfObjects[i];
if (listToDelete.indexOf(obj.id) !== -1) {
arrayOfObjects.splice(i, 1);
i--;
}
}
Pour éviter les suppressions linéaires, vous pouvez écrire les éléments de tableau que vous voulez garder sur le tableau:
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;
et pour éviter les recherches à temps linéaire dans une exécution moderne, vous pouvez utiliser un ensemble de hachage:
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;
qui peut être intégré à une fonction de Nice:
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 vous n’avez pas besoin de le faire sur place, c’est le Array#filter
:
const toDelete = new Set(['abc', 'efg']);
const newArray = arrayOfObjects.filter(obj => !toDelete.has(obj.id));
Vous pouvez supprimer un élément de l'une de ses propriétés sans utiliser de bibliothèque tierce comme celle-ci:
var removeIndex = array.map(function(item) { return item.id; })
.indexOf("abc");
~removeIndex && array.splice(removeIndex, 1);
findIndex fonctionne pour les navigateurs modernes:
var myArr = [{id:'a'},{id:'myid'},{id:'c'}];
var index = arr.findIndex(function(o){
return o.id === 'myid';
})
if (index !== -1) myArr.splice(index, 1);
Si vous voulez modifier le tableau existant lui-même, nous devons utiliser splice. Voici le moyen légèrement meilleur/lisible en utilisant findWhere de underscore/lodash:
var items= [{id:'abc',name:'oh'}, // delete me
{id:'efg',name:'em'},
{id:'hij',name:'ge'}];
items.splice(_.indexOf(items, _.findWhere(items, { id : "abc"})), 1);
(sans lodash/underscore)
À partir de ES5, nous avons la méthode findIndex
sur array, ce qui facilite son utilisation sans lodash/underscore
items.splice(items.findIndex(function(i){
return i.id === "abc";
}), 1);
(ES5 est supporté par presque tous les navigateurs morden)
Si vous voulez simplement le supprimer du tableau existant sans en créer un nouveau, essayez:
var items = [{Id: 1},{Id: 2},{Id: 3}];
items.splice(_.indexOf(items, _.find(items, function (item) { return item.Id === 2; })), 1);
Seulement JavaScript natif s'il vous plaît.
Une solution alternative plus "fonctionnelle", utilisant ECMAScript 5, vous pouvez utiliser:
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
arrayOfObjects.reduceRight(function(acc, obj, idx) {
if (listToDelete.indexOf(obj.id) > -1)
arrayOfObjects.splice(idx,1);
}, 0); // initial value set to avoid issues with the first item and
// when the array is empty.
console.log(arrayOfObjects);
[ { id: 'hij', name: 'ge' } ]
Selon la définition de 'Array.prototype.reduceRight' dans ECMA-262 :
reductionRight ne mute pas directement l'objet sur lequel il est appelé mais cet objet peut être muté par les appels à callbackfn.
Il s’agit donc d’un usage valide de reduceRight
.
Boucle en sens inverse en décrémentant i
pour éviter le problème:
for (var i = arrayOfObjects.length - 1; i >= 0; i--) {
var obj = arrayOfObjects[i];
if (listToDelete.indexOf(obj.id) !== -1) {
arrayOfObjects.splice(i, 1);
}
}
Ou utilisez filter
:
var newArray = arrayOfObjects.filter(function(obj) {
return listToDelete.indexOf(obj.id) === -1;
});
var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me
{id:'efg',name:'em'}, // delete me
{id:'hij',name:'ge'}] // all that should remain
selon votre réponse sera comme ça. Lorsque vous cliquez sur un objet particulier, envoyez l'index dans le paramètre pour la fonction me supprimer. Ce code simple fonctionnera comme un charme.
function deleteme(i){
if (i > -1) {
arrayOfObjects.splice(i, 1);
}
}
Vérifiez cela en utilisant Set et le filtre ES6.
let result = arrayOfObjects.filter( el => (-1 == listToDelete.indexOf(el.id)) );
console.log(result);
Voici JsFiddle: https://jsfiddle.net/jsq0a0p1/1/
Si vous aimez les paramètres courts et auto-descriptifs ou si vous ne voulez pas utiliser splice
et optez pour un filtre direct ou si vous êtes simplement une personne SQL comme moi:
function removeFromArrayOfHash(p_array_of_hash, p_key, p_value_to_remove){
return p_array_of_hash.filter((l_cur_row) => {return l_cur_row[p_key] != p_value_to_remove});
}
Et un exemple d'utilisation:
l_test_arr =
[
{
post_id: 1,
post_content: "Hey I am the first hash with id 1"
},
{
post_id: 2,
post_content: "This is item 2"
},
{
post_id: 1,
post_content: "And I am the second hash with id 1"
},
{
post_id: 3,
post_content: "This is item 3"
},
];
l_test_arr = removeFromArrayOfHash(l_test_arr, "post_id", 2); // gives both of the post_id 1 hashes and the post_id 3
l_test_arr = removeFromArrayOfHash(l_test_arr, "post_id", 1); // gives only post_id 3 (since 1 was removed in previous line)
avec filtre & indexOf
withLodash = _.filter(arrayOfObjects, (obj) => (listToDelete.indexOf(obj.id) === -1));
withoutLodash = arrayOfObjects.filter(obj => listToDelete.indexOf(obj.id) === -1);
avec filtre & comprend
withLodash = _.filter(arrayOfObjects, (obj) => (!listToDelete.includes(obj.id)))
withoutLodash = arrayOfObjects.filter(obj => !listToDelete.includes(obj.id));
Supprimer un objet par son identifiant dans un tableau donné;
const hero = [{'id' : 1, 'name' : 'hero1'}, {'id': 2, 'name' : 'hero2'}];
//remove hero1
const updatedHero = hero.filter(item => item.id !== 1);