Найти индекс самого длинного массива в массиве массивов
Если у вас есть массив, содержащий неопределенное количество массивов
Пример:
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).
Ответы
Ответ 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] ];
Однострочный:
masterArray.map(function(a){return a.length;}).indexOf(Math.max.apply(Math, masterArray.map(function(a){return a.length;})));
Но лучше кэшировать результаты map
.
var lengths = masterArray.map(function(a){return a.length;});
lengths.indexOf(Math.max.apply(Math, lengths));
Обратите внимание, что даже этот код перебирает массив 3 раза (map
, max
, indexOf
отдельно).
Для более эффективного использования вы должны использовать ручной итерационный массив.
var max = -Infinity;
var index = -1;
masterArray.forEach(function(a, i){
if (a.length>max) {
max = a.length;
index = i;
}
});
Reduce
метод:
masterArray.reduce(function(maxI,el,i,arr) {return el.length>arr[maxI].length ? i : maxI;}, 0)
Ответ 2
.reduce
- .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);
Ответ 3
masterArray.reduce(function(a,i,ii){
if (ii === 1){
return a
};
if (i.length > a.length){
return i
}
return a
})
Ответ 4
Редуктор выполняет итерацию массива массивов, где аккумулятор представляет индекс самого длинного массива, начиная с индекса 0
.
Для каждой итерации текущая длина элемента (который является массивом) сравнивается с длиной массива по индексу (аккумулятору) из списка массивов, и, если оно больше, аккумулятор увеличивается.
var arrays = [
[1,1,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]
]
var indexOfLongestArray = arrays.reduce((idx, arr) =>
arr.length > arrays[idx].length ? idx + 1 : idx
, 0)
// print result:
console.log( indexOfLongestArray )
Ответ 5
Lazy UnderscoreJS:
_.max(masterArray, function(i){ return i.length; })
Ответ 6
Сортируйте список индексов по длине в порядке убывания и возьмите первый:
a.map((e, i) => i) . sort((i, j) => a[j].length - a[i].length) [0]
Ответ 7
Если вы используете Lodash (начиная с версии 4.0), вы можете легко использовать _.maxBy
и _.size
как iteratee:
_.maxBy(masterArray, _.size) -> [1, 1, 1, 1, 2, 2, 2, 2, 4, 4]
Чтобы найти минимальное использование _.minBy
_.minBy(masterArray, _.size) -> [1, 2]
Ответ 8
Я столкнулся с этим сегодня и нашел этот вопрос.
Вот более современный подход:
const longestArray = masterArray.reduce((acc, curr, index) =>
curr.length > acc.length ? index : index - 1
);
- теперь код находит индекс самого длинного массива, а не самого длинного массива (извините, неправильно прочитал вопрос).
Ответ 9
Вы можете перебирать все элементы внешнего массива с помощью цикла 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));
Ответ 10
Попробуйте использовать цикл 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])
Ответ 11
Использование lodash:
_.max(_.map(masterArray, function(v, k) { return { id: k, size: v.length }; }),'size').id;
Это создает новый массив с объектами, имеющими "id" и "размер", затем находит максимальный размер в этом массиве и возвращает его "id".
jsfiddle:
https://jsfiddle.net/mckinleymedia/8xo5ywbc/
Ответ 12
если порядок элементов в массиве для вас не имеет значения, и вы хотите просто использовать самый длинный массив, вы можете отсортировать массив по длине
masterArray.sort((a, b) => b.length - a.length);
const theLongest = masterArray[0];
в этом случае первый элемент всегда будет самым длинным