2015-11-06 12 views
5

Se si dispone di una matrice contenente una quantità indefinita di arrayCome trovare più lunga serie in un array di array, in JavaScript

es:

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

Qual è un modo efficace per trovare l'indice di l'array più lungo in masterArray? (in questo indice di esempio sarebbe 2).

+1

efficiente in che modo? –

+0

Avrei dovuto essere più chiaro su questo. Intendevo solo in modo conciso, nulla sull'efficienza della memoria – jmancherje

risposta

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-liner è:

masterArray.map(function(a){return a.length;}).indexOf(Math.max.apply(Math, masterArray.map(function(a){return a.length;}))); 

Ma meglio di memorizzare nella cache map risultati.

var lengths = masterArray.map(function(a){return a.length;}); 
lengths.indexOf(Math.max.apply(Math, lengths)); 

nota, anche questo codice iterate matrice 3 volte (map, max, indexOf separatamente).
Per un funzionamento più efficiente, è necessario eseguire l'iterazione dell'array manuale.

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

Reduce metodo:

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 
 
})
approccio

+0

Ciò restituisce l'array più lungo, non il suo indice. –

2

pigro UnderscoreJS:

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

Restituisce la lunghezza più lunga anziché il suo indice. –

+0

Bene, restituisce effettivamente l'array secondario stesso. Sfiorò la domanda un po '. – djvs

1

È possibile iterare su tutte le voci della matrice esterna utilizzando un ciclo for e confrontare la lunghezza di ciascuno dei suoi elementi per la più lunga array che hai trovato finora.

La seguente funzione restituisce l'indice dell'array più lungo o -1 se l'array è vuoto.

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

Prova utilizzando while ciclo

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 cantare lodash:

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

Questo crea un nuovo array con gli oggetti che hanno 'id' e 'size', poi trova la dimensione massima di tale matrice, e restituisce la sua 'id'.

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

+0

Mi piace la soluzione di @ Downgoat meglio. –

2

.reduce è il modo più bello per fare questo:

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

O con ES6:

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

ordinare un elenco di indici di lunghezza in ordine decrescente, e prendi la prima:

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

Se si utilizza Lodash (a partire dalla versione 4.0) da poter usare facilmente _.maxBy e _.size come iteratee:

_.maxBy(masterArray, _.size) -> [1, 1, 1, 1, 2, 2, 2, 2, 4, 4] 

Per trovare il minimo impiego _.minBy

_.minBy(masterArray, _.size) -> [1, 2] 
Problemi correlati