2015-11-06 3 views
5

Если у вас есть массив, содержащий неопределенное количество массивовКак найти самый длинный массив в массиве массивов в JavaScript

например:

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

Efficient в каком смысле? –

+0

Я должен был быть более ясным. Я просто имел в виду в сжатом виде, ничего об эффективности памяти – jmancherje

ответ

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

One-вкладыш:

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

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

+0

Это возвращает самый длинный массив, а не его индекс. –

2

Ленивый UnderscoreJS подход:

_.max(masterArray, function(i){ return i.length; }) 
+2

Это возвращает длинную длину, а не ее индекс. –

+0

Ну, на самом деле возвращает сам суб-массив. Немного помолчал. – djvs

1

Вы можете перебрать все записи внешнего массива, используя 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

Попробуйте использовать 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])

1

U петь lodash:

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

Это создает новый массив с объектами, имеющими «идентификатор» и «размер», затем находит максимальный размер в этом массиве и возвращает его «идентификатор».

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

+0

Мне нравится решение @ Downgoat лучше. –

2

.reduce самый хороший способ сделать это:

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

Или с ES6:

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

Сортировать список индексов по длине в порядке убывания, и взять первый:

a.map((e, i) => i) . sort((i, j) => a[j].length - a[i].length) [0] 
1

Если вы используете 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] 
Смежные вопросы