2016-03-16 10 views
9

ho la matrice: [1,2,3,4,5,6,7]Array.map vuole mappare un valore a nulla

che voglio raggiungere: [[1,2], [3,4], [5,6], [7]]

sto pensando Array.map, ma non sembra essere in grado mappare a nulla per un elemento?

ho (usando Underscorejs):

arr.map(function(el, idx, arr) { 
    if (idx%2 != 0) return null; 
    if (idx == arr.length-1) return [el]; 
    return [el, arr[idx+1]] 
}).compact(); 

Questo è ancora un po 'brutto. Come posso ottenere la trasformazione (senza ciclo esplicito)?

+0

Puoi condividere ciò che hai provato finora? Inoltre non puoi evitare i loop. 'Array.map' creerà anche un loop. È un approccio solo più pulito. – Rajesh

risposta

6

reduce l'array usando l'operatore modulo:

function chunk(arr, n) { 
    return arr.reduce(function (p, c, i) { 
    if (i % n === 0) p.push([]); 
    p[p.length - 1].push(c); 
    return p; 
    }, []); 
} 

chunk(arr, 2); // [[1,2],[3,4],[5,6],[7]] 

DEMO

+0

Questo è un po 'quello che sto cercando. Grazie – Boyang

6

Il map function non può farlo, è una trasformazione che preserva la struttura.

Si potrebbe scrivere questa "suddivisione in blocchi" come un reduce, un ciclo normale, o qualcosa di strano come

var arr = [1,2,3,4,5,6,7]; 
return arr.filter(function(_, i) { 
    return i%2==0; 
}).map(function(x, i) { 
    return i*2+1<arr.length ? [x, arr[i*2+1]] : [x]; 
}); 

o

return arr.map(function(_, i) { 
    return arr.slice(i, 2); 
}).filter(function(_, i) { 
    return i%2==0; 
}) 

Vedi anche Split array into chunks per molte più varianti (alcuni dei quali piuttosto funzionale).

3

provare una combinazione di mappa e filtrare

var output = [1,2,3,4,5,6,7].map(function(value,index,arr){ 
    if(index%2==0) 
    { 
    //return [value, arr[index+1]]; 
    return index + 1 < arr.length ? [value, arr[index+1] ] : [ value ]; 
    } 
    else 
    { 
    return false; 
    } 
}).filter(function(value){return value}); 
console.log(output); 
+0

Indica l'indice fuori limite :) – Boyang

+0

@CharlesW. prova ora – gurvinder372

3

non puoi semplicemente fare qualcosa di simile?

modificato per evitare che vengano modificati originale, come da suggerimento di Andy

var temp = original.slice(); 
var newList = []; 
while(temp.length) 
{ 
    newList.push(temp.splice(0,2)); 
} 
+2

Questo potrebbe essere meglio non distruggere la matrice originale. Forse clonalo prima con 'var array2 = array.slice (0);'. – Andy

+0

1) Non ti ho minimizzato. 2) Stavo solo facendo un suggerimento. – Andy

4

più Una soluzione cablata in un loop.

var array = [1, 2, 3, 4, 5, 6, 7], 
 
    result = array.reduce(function (r, a, i) { 
 
     i & 1 && r[i >> 1].push(a) || r.push([a]); 
 
     return r; 
 
    }, []); 
 

 
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

o funzionale (è utilizzata Fat_Freddy's idea)

function due(array) { 
 
    return array.length && [array.splice(0, 2)].concat(due(array)) || []; 
 
} 
 

 
var array = [1, 2, 3, 4, 5, 6, 7], 
 
    result = due(array.slice()); 
 

 
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

+0

Ottima risposta specialmente 'causa()', ma cambierà la matrice originale. Suggerirei di usare 'array.slice()', ma suppongo che la ricorsione non funzionerà. – Rajesh

+0

@Rajesh, vedere modifica. –

1

Si può provare array.slice() e mentre ciclo per esso.

Anche l'utilizzo di funzioni come map, filter itererà ogni elemento.

function splitArrayInLength(arr, len) { 
 
    var returnArr = []; 
 
    var index = 0; 
 
    while(index < arr.length){ 
 
    returnArr.push(arr.slice(index, index + len)); 
 
    index += len; 
 
    } 
 
    return returnArr; 
 
} 
 

 
function main() { 
 
    var arr = [1, 2, 3, 4, 5, 6, 7]; 
 
    print(splitArrayInLength(arr, 2)); 
 
    print(splitArrayInLength(arr, 4)); 
 
} 
 

 
function print(obj){ 
 
    document.write("<pre>" + JSON.stringify(obj, 0, 4) + "</pre><br/>"); 
 
} 
 

 
main();

Problemi correlati