2016-03-16 14 views
9

Mam tablicy: [1,2,3,4,5,6,7]Array.map chcesz mapować wartości do niczego

chcę osiągnąć: [[1,2], [3,4], [5,6], [7]]

myślę Array.map, ale nie wydaje się, aby móc mapować na nic dla elementu?

mam (używając underscore.js):

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(); 

To wciąż nieco brzydki. Jak mogę osiągnąć transformację (bez jawnej pętli)?

+0

można dzielić co próbowałeś do tej pory? Ponadto nie można uniknąć pętli. 'Array.map' również utworzy pętlę. Jest to po prostu bardziej czyste podejście. – Rajesh

Odpowiedz

6

reduce tablicy za pomocą operatora 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

Jest to coś, czego szukam. Dzięki – Boyang

6

Nie można tego zrobić, jest to transformacja zachowująca strukturę.

Można napisać to „wyrwy” jako reduce, zwykłej pętli, albo coś dziwnego jak

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]; 
}); 

lub

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

Zobacz również Split array into chunks przez wiele wariantów (niektóre z nich dość funkcjonalny).

3

Spróbuj kombinacji mapie i filtrować

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

Daje indeks poza oprawą :) – Boyang

+0

@CharlesW. spróbuj teraz – gurvinder372

3

Nie można po prostu zrobić coś takiego?

przygotowane do zapobiegania oryginału zmieniany zgodnie Andy sugestii

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

To może być lepsze, ale nie zniszczyło oryginalnej tablicy. Być może najpierw sklonuj go za pomocą 'var array2 = array.slice (0);'. – Andy

+0

1) Nie zabrałem ci głosu. 2) Właśnie robiłem sugestię. – Andy

4

jedno przewodowe w jednej pętli.

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>');

lub funkcjonalne (ona wykorzystana 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

Świetna odpowiedź specjalnie 'due()', ale zmieni oryginalną tablicę. Proponuję zamiast tego używać 'array.slice()', ale wtedy rekursja nie będzie działać. – Rajesh

+0

@Rajesh, patrz edycja. –

1

Można spróbować array.slice() a jednocześnie pętlę dla niego.

Również za pomocą funkcji takich jak map, filter będzie iterować każdy element.

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();