在一个数组中查找最长数组的索引。该数组是由多个数组组成的。

25
如果您有一个包含不确定数量的数组的数组

例如:

var masterArray = [ [1,2,3,4,5],
                    [1,2], 
                    [1,1,1,1,2,2,2,2,4,4],
                    [1,2,3,4,5] ];

如何高效地找到masterArray中最长数组的索引?(在这个例子中,索引为2。)


2
以什么方式高效? - user663031
我应该更清楚一些。我只是指以简洁的方式表达,与内存效率无关。 - jmancherje
在多个长度最大的数组的情况下,你希望会发生什么? - akurtser
10个回答

34

一句话概括:

masterArray
  .map(a=>a.length)
  .indexOf(Math.max(...masterArray.map(a=>a.length)));

但最好缓存masterArray.map(a=>a.length)的结果。

const lengths = masterArray.map(a=>a.length);
lengths.indexOf(Math.max(...lengths));

请注意,该代码仍然至少迭代数组3次(单独使用mapmaxindexOf)。

*展开运算符是为了提高可读性,可以省略不写


为了更高效,您应该手动迭代数组。

let max = -Infinity;
let index = -1;
masterArray.forEach(function(a, i){
  if (a.length > max) {
    max = a.length;
    index = i;
  }
});

Reduce 方法:

masterArray.reduce((maxI,el,i,arr) => 
    (el.length>arr[maxI].length) ? i : maxI, 0);

16

.reduce 是实现这个操作最好的方式:

masterArray.reduce(function (pending, cur, index, ar) { ar[ pending ].length > cur.length ? pending : index }, 0);

或者使用 ES6:

masterArray.reduce((p, c, i, a) => a[p].length > c.length ? p : i, 0);

1
条件将是 a[p].length > c.length ? p : i - xkeshav
这是我见过的对于这个问题最优雅的答案。 - Rick
是的,这是一个更好的答案。甚至可以放弃索引使用直接引用。collection.reduce((a, b) => (a.length > b.length ? a : b),[]); - stwilz
很好,但如果你的数组之一为空,则无法正常工作。 - Florent Arlandis

5

一个 reducer 迭代数组的数组,其中累加器表示最长数组的索引,从索引 0 开始。

每次迭代比较当前项(数组)的 length 和当前找到的最长数组的 lengtharrays[acc]),如果更大,则将累加器设置为该 index

var arrays = [ 
  [1,1,1,1,1],
  [1,1], 
  [1,1,1,1,1,1,1,1],   // ⬅ The longest, which is at index 2
  [1,1,1,1],
  [1,1,1,1,1,1]
]

var indexOfLongestArray = arrays.reduce((acc, arr, idx) => {
  console.log(acc, idx, JSON.stringify([arr, arrays[acc]]))
  return arr.length > arrays[acc].length ? idx : acc
}, 0)

// print result:
console.log( "longest array is at index: ", indexOfLongestArray )

简短的函数:

var indexOfLongestArray = list => list.reduce((a, arr, idx) => 
  arr.length > arrays[a].length ? idx : a
, 0)

1
"idx + 1" 看起来太可疑了,绝不可能正确 =) - vp_arth
1
@vp_arth - 是的 :) 我不记得为什么我写成那样了,但是在你的评论后,我重新编写了答案。感谢你让我知道! - vsync

3

masterArray.reduce(function(a,i,ii){
  if (ii === 1){
    return a
  };
  if (i.length > a.length){
    return i
  }
  return a
})


2
这将返回最长的数组,而不是它的索引。 - user663031

1
按长度降序排序索引列表,并取第一个:
a.map((e, i) => i) . sort((i, j) => a[j].length - a[i].length) [0]

0

使用 lodash:

_.max(_.map(masterArray, function(v, k) { return { id: k, size: v.length }; }),'size').id;

这将创建一个新的数组,其中包含具有'id'和'size'属性的对象,然后在该数组中查找最大的'size'值,并返回其对应的'id'。

jsfiddle: https://jsfiddle.net/mckinleymedia/8xo5ywbc/


我更喜欢@Downgoat的解决方案。 - William Schroeder McKinley

0

使用 lodash _.maxBy

let a = [[1,2,3,4],[1,3,2,33,3,3,3,32,2,3,31,1],[1]]
console.log(_.maxBy(a, i=>i.length))
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>


0

您可以使用 for 循环遍历外部数组的所有条目,并将其每个项的长度与迄今为止找到的最长数组进行比较。

以下函数返回最长数组的索引,如果数组为空,则返回 -1

function indexOfLongest(arrays) {
  var longest = -1;
  for (var i = 0; i < arrays.length; i++) {
    if (longest == -1 || arrays[i].length > arrays[longest].length) {
      longest = i;
    }
  }
  return longest;
}  

var masterArray = [ [1,2,3,4,5],
                    [1,2], 
                    [1,1,1,1,2,2,2,2,4,4],
                    [1,2,3,4,5] ];
document.write(indexOfLongest(masterArray));


-1

一种基础且教学性强的解决方案

var masterArray = [ [1,2,3,4,5],
                    [1,2], 
                    [1,1,1,1,2,2,2,2,4,4],
                    [1,2,3,4,5] ];

let maxIndex = -1
let currMax = 0;

for (const i in masterArray) {
   if (masterArray[i].length > currMax) {
     currMax = masterArray[i].length
     maxIndex = i
   }
}

console.log(maxIndex)

-1

尝试使用while循环

var masterArray = [
  [1, 2, 3, 4, 5],
  [1, 2],
  [1, 1, 1, 1, 2, 2, 2, 2, 4, 4],
  [1, 2, 3, 4, 5]
];

var i = 0, len = masterArray.length;

while (i < len) {
  // if array[i + 1] exists
  // and array[i + 1] length greater than array[i] length
  // and i + 1 equals array length - 1
  // break
  if (masterArray[i + 1] 
      && masterArray[i + 1].length < masterArray[i].length 
      && i + 1 === len - 1) {
    break
  } 
  // else increment i
  else {
    ++i
  }
}

console.log(masterArray[i])


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