【问题标题】:return array of indices of all values in an array in Javascript在Javascript中返回数组中所有值的索引数组
【发布时间】:2019-11-22 03:30:23
【问题描述】:

我有一个数组数组,我想得到一个元素索引的数组。 我从这个开始:

[
  [1,2,3],
  [-1],
  [-1],
  [4,5,6],
  [-1],
  [],
  []
]

我想要:

[1,2,4]

有些元素可能还没有被填充(它们会随着时间的推移而被填充),但我想指定哪些元素是故意为空的。这就是 -1 的含义(我可以很容易地使用 null)。

我确定 filter 是正确的使用方法,但我不想要该元素;我只想要元素的索引。

我确信我可以通过几个循环和迭代来做到这一点,但这似乎有点过头了。

【问题讨论】:

  • 谢谢,虽然我从来没有理解过 map - 它是如此...抽象和灵活 - 并且不知道我将如何实现它。我会尽力解决这个问题。
  • .map 必须在原始数组的每次迭代时将某些内容返回到结果数组中。如果您想在结果数组中排除与您的条件不匹配的条目,.map 不会这样做。
  • 抱歉我很快就回复了,在这种情况下你会使用 array.reduce developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • 您的方案的最佳方法是使用reduce,因为它已经得到回答。

标签: javascript arrays filter


【解决方案1】:

这可能是更多的手册,但非常容易理解。

let input = [
  [1,2,3],
  [-1],
  [-1],
  [4,5,6],
  [-1],
  [],
  []
];

let output = [];

// Loop over original array
input.forEach(function(item, index){
    // If length of current item is 1 and that one item is the "deliberately 
    // empty" indicator, push its index into result array
    item.length === 1 && item[0] === -1 ? output.push(index) : null;
});

console.log(output);

【讨论】:

  • 还有item.length === 1 && item[0] === -1 && output.push(index);,它避免了null和三元,但也许只写一个if是最清楚的。变量也可以是const
  • 哇。我已经离开 vanilla JS 这么久了,我不知道它有一个原生的 forEach 函数。我会检查一下。这不是魔法!
【解决方案2】:

您可以使用Array#reduce 的第三个参数来访问每个元素的索引,然后如果当前元素与您的标志变量匹配,则使用回调有条件地扩展结果数组。

const result = [
  [1,2,3],
  [-1],
  [-1],
  [4,5,6],
  [-1],
  [],
  []
].reduce((a, e, i) => e.length === 1 && e[0] === -1 ? a.concat(i) : a, []);

console.log(result);

话虽如此,您的原始版本以及使用null 而不是[-1] magic number 的建议似乎不太容易出错。下面是测试 null 元素与空数组不同的代码:

const emptyIdxes = [
  [1,2,3],
  [],
  null,
  [7,8,9],
  null
].reduce((a, e, i) => e === null ? a.concat(i) : a, []);

console.log(emptyIdxes);

【讨论】:

  • 我不确定您的第二个代码 sn-p 是否正常工作,因为数组中的某些条目可能为空 - 如果您的第二个代码 sn-p 的输入与第一个sn-p?
  • 我试过了,它可以工作(使用-1)。缺点是,对我来说,这很神奇。
  • @Nick 我不太明白。在底部的 sn-p 中,我正在谈论使用与 [-1] 不同的方案作为标志 - 回到使用 []null 作为标志。所以在底部输入上使用顶部输入实际上没有意义(它会返回[5, 6])。
  • @ggorlen 在您的第二种方法中无法区分空数组(没有写入)和故意为空的数组(具有 null/-1 值的数组)
  • 很奇怪。它不适用于 null 或 "" - 它们返回一个空数组。它仅适用于-1。我仔细检查了测试“null”的语法。不幸的是,-1 被视为数组中元素的有效值,因此它在总计和显示中增加。这意味着我需要进行后续测试才能清除 -1。
【解决方案3】:

这就是我如何实现 Scott Marcus 的建议,即使用 forEach 循环手动生成新数组。

虽然使用 map()、reduce() 或 filter() 的其他解决方案可能更快或需要更少的处理周期,但我更喜欢这种解决方案,因为它更具可读性和可调试性。这很重要,因为希望这段代码比我参与其中的寿命更长,并且下一个编码员应该能够轻松破译它。

下面是一个示例输入。它是飞镖比赛前十周的(外部)数组,每个元素都是它自己的(内部)数组,包含八支球队的得分。到目前为止,只有前两周得分。

第 7 周和第 8 周是假期,因此应该在 HTML 表格中显示为灰色。无论打了多少周,都可以在赛季开始时标记假期。

var arrScore = [
  [2,1,1,2,2,1,2,1],
  [2,2,2,0,1,1,3,1],
  [],
  [],
  [],
  [],
  [null],/* holiday */
  [null],/* holiday */
  [],
  [] /* etc. */
];

因为我在与分数不同的函数中处理假期,所以我想要一个干净的(新)数组,这样我就可以在几周内运行并标记假期,而与处理评分无关。而作为假期的空周(因此永远不会有分数)必须与那些没有分数的周区分开来。

根据上面的例子,我想要的(新)数组是 [6,7],它是 [null] 元素的(从零开始的)索引。

arrScore.forEach(function(item, index){
    item.length === 1 && item[0] === null ? holidays.push(index) : null;
});

console.log(holidays);

=

[6,7]

forEach() 只是迭代(外部)数组,如果它找到一个元素

  • 是一个长度为 1 的(内部)数组,并且
  • 该(内部)数组的第一个元素为空,

它只是将该元素的索引(外部数组的)推送到一个新的假期数组中。

【讨论】:

  • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
【解决方案4】:

你也可以使用map函数

var arr = [
    [1, 2, 3],
    [-1],
    [-1],
    [4, 5, 6],
    [-1],
    [],
    []];

    
var arr2 = [];
const map1 = arr.map(x => x == -1 ? arr2.push(arr.indexOf(x)) : "");

console.log(arr2);

【讨论】:

  • 原来 -1 被解释为有效的数组元素,并被处理为有效值,所以我毕竟不能使用它。我用 null 和 'null' 尝试了你的技术,但它们输出一个空数组。
  • 当你不关心地图的结果时,为什么要使用map而不是forEach
  • @JohnMontgomery 因为在问题中他明确表示他不想循环。“我确信我可以通过几个循环和迭代来做到这一点,但这似乎有点过头了。 "而且我没有使用过滤器功能,因为已经有使用过滤器的答案。
  • @SachinthaNayanajith 如果forEach 是一个循环,那么map 也是如此。它们实际上完全相同,只是 map 也返回一个值。
猜你喜欢
  • 2021-08-01
  • 2018-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-03
  • 2016-11-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多