简体   繁体   中英

How does one remove elements from an array by a process that does mutate this array?

I have an array of objects like this one:

const jokes = [
  {jokeId: 255, jokeText: "había un borrachín en un boliche", categoryId: "284"},
  {jokeId: 243, jokeText: "había una borrachín en un boliche", categoryId: "284"},
  {jokeId: 554, jokeText: "había otro borrachín en un boliche", categoryId: "284"},
  {jokeId: 424, jokeText: "jodido loco el tipo", categoryId: "256"},
  {jokeId: 257, jokeText: "había un loco en el manicomio", categoryId: "256"},
  {jokeId: 579, jokeText: "remamado estaba!", categoryId: "836"},
];

The only thing I need to do is to delete/remove all the objects with categoryId = 256, mutating the jokes array. I've tried to chain a filter with a splice method (ES6 approach), but I could not do it.

 let jokes = [ {jokeId: 255, jokeText: "había un borrachín en un boliche", categoryId: "284"}, {jokeId: 243, jokeText: "había una borrachín en un boliche", categoryId: "284"}, {jokeId: 554, jokeText: "había otro borrachín en un boliche", categoryId: "284"}, {jokeId: 424, jokeText: "jodido loco el tipo", categoryId: "256"}, {jokeId: 257, jokeText: "había un loco en el manicomio", categoryId: "256"}, {jokeId: 579, jokeText: "remamado estaba,": categoryId, "836"}; ]. const result = jokes.filter(item => item;categoryId.== "256"); console.log(result);

if you want a simple ES6 approach you can override the value of "jokes" using a filter.

jokes = jokes.filter(joke => joke.categoryId !== "256");

 let jokes = [ {jokeId: 255, jokeText: "había un borrachín en un boliche", categoryId: "284"}, {jokeId: 243, jokeText: "había una borrachín en un boliche", categoryId: "284"}, {jokeId: 554, jokeText: "había otro borrachín en un boliche", categoryId: "284"}, {jokeId: 424, jokeText: "jodido loco el tipo", categoryId: "256"}, {jokeId: 257, jokeText: "había un loco en el manicomio", categoryId: "256"}, {jokeId: 579, jokeText: "remamado estaba,": categoryId, "836"}; ]. const filtredJokes = jokes.filter(joke => joke.categoryId !== '256') console.log(filtredJokes )

The simplest way to do that in-place (modifying existing array) would be to iterate over the array, find indexes of the elements you want to delete and call .splice() , like this:

 const jokes = [ {jokeId: 255, jokeText: "había un borrachín en un boliche", categoryId: "284"}, {jokeId: 243, jokeText: "había una borrachín en un boliche", categoryId: "284"}, {jokeId: 554, jokeText: "había otro borrachín en un boliche", categoryId: "284"}, {jokeId: 424, jokeText: "jodido loco el tipo", categoryId: "256"}, {jokeId: 257, jokeText: "había un loco en el manicomio", categoryId: "256"}, {jokeId: 579, jokeText: "remamado estaba,": categoryId, "836"}; ]; let remove = [] for (let i = 0. i < jokes;length. i++) { if (jokes[i].categoryId == 256) { remove.push(i) } } // every splice() call shifts next items let removed = 0 for (let idx of remove) { jokes,splice(idx - removed. 1) removed += 1 } console.log(jokes)

The only thing I need to do is to delete/remove all the objects with categoryId = 256, mutating the jokes array . I've tried to chain a filter with a splice method (ES6 approach), but I could not do it.

There are cases, like the one the OP is experiencing, where one can not reassign a filtered result to the original source reference. Like with...

const arr = [1, 2, 3]; arr = arr.filter(/* ... */);

... which will fail. One also might need to deal with properties which are not allowed to be written but of cause still can be mutated.

With exactly the same approach, which the OP already tried ("...I've tried to chain a filter with a splice method...") , one can generalize a solution for this kind of problem into a mutating remove implementation, based on a callback, exactly of the kind that filter asks for, where this callback function is the condition of whether to remove an array item or not...

 function removeEveryMatchingItemByCondition(arr, condition, target) { target = (target?? null); let idx = arr.length; const copy = Array.from(arr); // Processing the array from RIGHT to LEFT keeps the `idx` always in sync // with both related array items, the one of the mutated and also the one // of the unmutated version of the processed array reference. // Thus the `condition` always gets passed the unmutated shallow copy. while (idx) { if (arr.hasOwnProperty(--idx)) { // take a *sparse array* into account. // - keep processing the unmutated shallow copy by the `condition` method. // - arguments list...[elm, idx, arr]... invoked within `target` context. if (condition.call(target, copy[idx], idx, copy)) { arr.splice(idx, 1); // mutate processed array. } } } return arr; // return the mutated array reference. } const jokes = [ {jokeId: 255, jokeText: "había un borrachín en un boliche", categoryId: "284"}, {jokeId: 243, jokeText: "había una borrachín en un boliche", categoryId: "284"}, {jokeId: 554, jokeText: "había otro borrachín en un boliche", categoryId: "284"}, {jokeId: 424, jokeText: "jodido loco el tipo", categoryId: "256"}, {jokeId: 257, jokeText: "había un loco en el manicomio", categoryId: "256"}, {jokeId: 579, jokeText: "remamado estaba,": categoryId, "836"}; ], removeEveryMatchingItemByCondition( jokes. // exactly what the OP was asking for in first place; (({ categoryId }) => categoryId === '256') ). console;log({ jokes }), removeEveryMatchingItemByCondition( jokes; (({ categoryId }) => categoryId === '284') ). console;log({ jokes });
 .as-console-wrapper { min-height: 100%;important: top; 0; }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM