如何通过改变数组的进程从数组中删除元素?
How does one remove elements from an array by a process that does mutate this array?
我有一组这样的对象:
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"},
];
我唯一需要做的就是 delete/remove 所有 categoryId = 256 的对象,改变 jokes 数组。
我尝试将 filter 与 splice 方法(ES6 方法)链接起来,但我做不到。
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);
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 )
如果您想要一个简单的 ES6 方法,您可以使用过滤器覆盖“jokes”的值。
jokes = jokes.filter(joke => joke.categoryId !== "256");
就地执行此操作(修改现有数组)的最简单方法是遍历数组,找到要删除的元素的索引并调用 .splice()
,如下所示:
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.
在某些情况下,例如 OP 遇到的情况,无法将过滤后的结果重新分配给原始源引用。喜欢...
const arr = [1, 2, 3]; arr = arr.filter(/* ... */);
...这将失败。一个人可能还需要处理不允许写入但仍然可以改变的属性。
使用与 OP 已经尝试过的完全相同的方法 ("...我尝试将 filter
与 splice
方法链接起来..." ),可以将此类问题的解决方案归纳为 mutating remove 实现,基于回调,正是 filter
要求的那种,这里的回调函数是判断是否移除数组项的条件...
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; }
我有一组这样的对象:
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"},
];
我唯一需要做的就是 delete/remove 所有 categoryId = 256 的对象,改变 jokes 数组。 我尝试将 filter 与 splice 方法(ES6 方法)链接起来,但我做不到。
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);
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 )
如果您想要一个简单的 ES6 方法,您可以使用过滤器覆盖“jokes”的值。
jokes = jokes.filter(joke => joke.categoryId !== "256");
就地执行此操作(修改现有数组)的最简单方法是遍历数组,找到要删除的元素的索引并调用 .splice()
,如下所示:
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 asplice
method (ES6 approach), but I could not do it.
在某些情况下,例如 OP 遇到的情况,无法将过滤后的结果重新分配给原始源引用。喜欢...
const arr = [1, 2, 3]; arr = arr.filter(/* ... */);
...这将失败。一个人可能还需要处理不允许写入但仍然可以改变的属性。
使用与 OP 已经尝试过的完全相同的方法 ("...我尝试将 filter
与 splice
方法链接起来..." ),可以将此类问题的解决方案归纳为 mutating remove 实现,基于回调,正是 filter
要求的那种,这里的回调函数是判断是否移除数组项的条件...
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; }