从数组中删除除特定元素外的所有元素

5
我是一名有用的助手,可以为您翻译文本。

我有两个数组。第一个是索引数组,第二个是对象数组。它们看起来像这样:

var nums = [0, 2];
var obj = [Object_1, Object_2, Object_3];

在这种情况下,我需要删除所有的“obj”元素,除了obj[0]obj[2]。因此,结果将如下所示:

obj = [Object_2]

有时候可能会出现nums = [0, 1, 2]obj = [Object_1, Object_2, Object_3]的情况,这种情况下我不需要移除任何元素。

"obj"的长度总是大于"nums"的长度。

因此,我开始只寻找需要保存的元素:

nums.forEach(function(key) {
    obj.forEach(function(o, o_key) {
        if (key === o_key) {
            console.log(key, o);
            // deleting remaining elements
        }
    });
});

问题:如何删除不符合我的条件的元素?我不需要新数组,我想修改现有的“obj”数组。如何实现此功能?或者我应该使用其他技术吗?

2
为什么在第一个情况下要删除给定的索引,在第二个情况下却相反? - Nina Scholz
我同意@NinaScholz的观点,第二种情况应该是nums = [] - George
3个回答

5

如果nums是一个包含你想保留元素索引的数组,你可以使用过滤器来实现这一点。

obj = obj.filter((o, i) => nums.indexOf(i) > -1); 

1
OP提到不想要一个新的数组。 - Ovidiu Dolha
这并不会创建一个新的数组,它只是对现有的数组进行了过滤。 - MunkyJunky
1
filter返回一个新的数组 - 请参见https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/filter?v=control中的第一行。 - Ovidiu Dolha
是的,它确实可以。但是根据问题中提到不想要一个新数组,我理解为OP不想要另一个变量来存储另一个数组。如果OP需要的是完全相同的数组,则我的答案是错误的。这个答案开始时有两个变量存储数组,并且结束时仍然是同样的两个变量存储数组。 - MunkyJunky
在我看来,实际的数组对象很重要;让相同的变量引用指向一个新对象并不是一个值得考虑的用例(这有什么意义呢?)然而,保持相同的对象可能很重要——这取决于对象的用途。 - Ovidiu Dolha

5
你可以检查索引的长度是否与对象数组的长度相同,并返回或删除给定索引处的对象。
需要排序后的索引数组,因为Array#splice会改变数组的长度。(如果使用降序排列的索引数组,可以使用Array#forEach代替Array#reduceRight。)

function mutate(objects, indices) {
    if (objects.length === indices.length) {
        return;
    }
    indices.reduceRight(function (_, i) {
        objects.splice(i, 1);
    }, null);
}

var objects = [{ o: 1 }, { o: 2 }, { o: 3 }];

mutate(objects, [0, 1, 2]);               // keep all items
console.log(objects); 

objects = [{ o: 1 }, { o: 2 }, { o: 3 }]; // delete items at index 0 and 2
mutate(objects, [0, 2]);
console.log(objects);
.as-console-wrapper { max-height: 100% !important; top: 0; }


相反的情况怎么办?如果我想要保存指定索引处的项目,例如[0, 2],并删除第1个索引下的元素,应该使用哪个函数而不是reduceRight()更好呢?抱歉打扰了) - Luchnik
@Luchnik,我建议迭代“objects”,获取索引的最大值并检查实际索引,如果需要,则进行切片。 - Nina Scholz

1
如果要保留相同的数组对象,您需要使用 splice ,例如在简单的反向 for 中,为了不混淆索引:
for (var i=obj.length-1; i>=0; i--) {
    if (nums.indexOf(i) < 0) {
        obj.splice(i, 1);
    }
}

假设索引列表(nums)已排序。如果没有排序,我们需要先对其进行排序:
var sortedNums = nums.sort(function (a, b) {  return a - b;  });

然后使用已排序的数字 sortedNums 来检查 indexOf。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接