2016-03-16 16 views
9

Tôi có mảng: [1,2,3,4,5,6,7]Array.map muốn ánh xạ giá trị không có gì

tôi muốn đạt được: [[1,2], [3,4], [5,6], [7]]

Tôi đang nghĩ đến Array.map, nhưng nó dường như không có khả năng để ánh xạ tới không có gì cho một phần tử?

Tôi đã (sử dụng 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(); 

này vẫn còn một chút xấu xí. Làm thế nào tôi có thể đạt được chuyển đổi (không có vòng lặp rõ ràng)?

+0

Bạn có thể chia sẻ những gì đã bạn đã cố gắng cho đến nay? Ngoài ra, bạn không thể tránh vòng lặp. 'Array.map' cũng sẽ tạo ra một vòng lặp. Cách tiếp cận của nó sạch hơn. – Rajesh

Trả lời

6

reduce mảng sử dụng toán tử 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

Đây là loại nội dung tôi đang tìm kiếm. Cảm ơn – Boyang

6

map function không thể làm điều đó, đó là một chuyển đổi cấu trúc bảo toàn.

Bạn có thể viết này "chunking" như một reduce, một vòng lặp đơn giản, hoặc một cái gì đó kỳ lạ như

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

hoặc

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

Xem thêm Split array into chunks đối với nhiều biến thể hơn (một số trong số họ khá chức năng).

3

Hãy thử một sự kết hợp của bản đồ và lọc

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

Cung cấp chỉ mục ngoài giới hạn :) – Boyang

+0

@CharlesW. hãy thử ngay bây giờ – gurvinder372

3

thể bạn không chỉ cần làm điều gì đó như thế này?

chỉnh sửa để ngăn chặn gốc không bị thay thế, theo gợi ý của Andy

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

Điều này có thể tốt hơn là nó không phá hủy mảng ban đầu. Có lẽ sao chép nó trước tiên với 'var array2 = array.slice (0);'. – Andy

+0

1) Tôi không downvote bạn. 2) Tôi vừa đưa ra một gợi ý. – Andy

4

hơn Một giải pháp có dây trong một vòng lặp.

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

Hoặc chức năng (nó sử dụng 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

Câu trả lời tuyệt vời đặc biệt 'do()', nhưng nó sẽ thay đổi mảng ban đầu. Tôi muốn đề nghị sử dụng 'array.slice()' thay vào đó, nhưng sau đó tôi đoán đệ quy sẽ không hoạt động. – Rajesh

+0

@Rajesh, vui lòng xem chỉnh sửa. –

1

Bạn có thể thử array.slice() và trong khi vòng lặp cho nó.

Cũng sử dụng chức năng như map, filter sẽ lặp lại mọi thành phần.

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

Các vấn đề liên quan