如何基于JavaScript中另一个数组的索引选择数组元素?

12

这个方法是可行的,但我想知道是否有更好的按索引筛选的方式:

a = [10,20,30,40]
b = [1,3]
a.filter((x,i) => b.includes(i))
// [20, 40]

@Redu,这只适用于连续的代码块。 - Sasang
抱歉,我的代码有错误。我已经更新了问题。 - nachocab
3
你改变了问题,所以现在你需要执行 b.map(i => a[i]),假设 b 始终携带映射到 a 中某个项目的索引。 - Redu
@Redu没错,这比我做的好。我以为可能会有类似a.select(b)的东西。 - nachocab
3个回答

11

另一种方法是b.map(aIndex => a[aIndex])。如果ba短,这样做可能会更快。但是,如果b中有不属于a的索引,则最终会在数组中出现undefined "空洞"。

编辑

看起来Array.includes的运行时间复杂度对于未排序的数组为O(n)。 如果我们将A = a.lengthB = b.length,则您在问题中的解决方案应该在O(A * B)中运行。第二个解决方案(使用map)将在O(B)中运行。要修复undefined的空洞,您可以添加一个.filter(element => typeof element !== 'undefined')。最终的解决方案将是b.map(i => a[i]).filter(e => typeof e !== 'undefined')。现在它的运行时间复杂度是O(2 * B),这应该仍然比O(A * B)好。


2
可以使用Lodash的at函数来实现这个(以及更多)功能:
_.at([10, 20, 30, 40], [1, 3]) // [20, 40]
_.at(['a', 'b'], [0, 1, 1, 0]) // ['a', 'b', 'b', 'a']

2
我认为您的解决方案非常好。 map 也是一个很好的解决方案。
顺便说一下,你可以使用 for...of 循环,但这样做变得更加复杂而没有必要...

let a = [10, 20, 30, 40],
    b = [1, 3];

let res = [];
for (const entry of a.entries()) {
  if (b.includes(entry[0])) {
    res.push(entry[1]);
  }
}

console.log(res);


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