【问题标题】:Remove elements from array except particular one从数组中删除除特定元素之外的元素
【发布时间】:2017-05-24 11:31:44
【问题描述】:

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

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

在这种特殊情况下,我需要删除除obj[0]obj[2] 之外的所有“obj”元素。所以结果会是这样的:

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”数组。我怎样才能实现这个功能?还是我应该使用其他一些技术?

【问题讨论】:

  • 为什么在第一种情况下删除给定的索引而在第二种情况下相反?
  • 我同意@NinaScholz 第二个案例不应该是nums = []

标签: javascript arrays algorithm array-splice


【解决方案1】:

您可以检查索引的长度是否与对象数组的长度相同,并返回或删除给定索引处的对象。

它需要一个用于索引的排序数组,因为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,然后我建议迭代objects,获取索引的最大值并检查实际索引,然后在必要时进行拼接。
【解决方案2】:

您可以使用过滤器执行此操作,假设 nums 是您要保留的元素索引的数组。

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

【讨论】:

  • OP 提到不想要一个新数组
  • 这不会创建新数组,它会过滤现有数组
  • 过滤器返回一个新数组 - 见developer.mozilla.org/en/docs/Web/JavaScript/Reference/…中的第一行
  • 是的,但我认为在这个问题中不想要一个新数组意味着 OP 不想要一个新变量存储另一个数组。如果 OP 需要数组是 exact 相同的数组,那么我的答案是不正确的。这个答案以 2 个保存数组的变量开始,以同样的 2 个保存数组的变量结束。
  • 我也觉得实际的数组对象很重要;具有指向新对象的相同变量引用并不是真正值得考虑的用例(它有什么意义?)但是维护相同的对象可能很重要 - 取决于对象的用途
【解决方案3】:

如果你想保持相同的数组对象,你需要使用splice e.g.在一个简单的反向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

【讨论】:

    猜你喜欢
    • 2019-06-03
    • 1970-01-01
    • 2016-02-12
    • 2018-04-16
    • 2021-04-21
    • 2016-08-02
    • 2020-06-29
    • 1970-01-01
    相关资源
    最近更新 更多