Chuyển đổi ES6 có thể lặp lại thành mảng


100

Giả sử bạn có một mảng giống như Javascript ES6 Lặp lại mà bạn biết trước là sẽ có độ dài hữu hạn, cách tốt nhất để chuyển đổi nó thành một Mảng Javascript là gì?

Lý do làm như vậy là nhiều thư viện js như dấu gạch dưới và lodash chỉ hỗ trợ Mảng, vì vậy nếu bạn muốn sử dụng bất kỳ chức năng nào của chúng trên Lặp lại, trước tiên nó phải được chuyển đổi thành Mảng.

Trong python, bạn chỉ có thể sử dụng hàm list (). Có tương đương trong ES6 không?


26
Array.from(iterable), xem bản nháp ECMA-262 ed 6 .
RobG

Câu trả lời:


155

Bạn có thể sử dụng Array.from hoặc toán tử spread .

Thí dụ:

let x = new Set([ 1, 2, 3, 4 ]);

let y = Array.from(x);
console.log(y); // = [ 1, 2, 3, 4 ]

let z = [ ...x ];
console.log(z); // = [ 1, 2, 3, 4 ]


2
Gần như điều tương tự cũng áp dụng cho let m = new Map()cấu trúc dữ liệu ES6 : chỉ lấy các giá trị của Bản đồ, sử dụng Array.fromhoặc trải toán tử trên m.values(), tương tự đối với m.keys(). Nếu không, bạn sẽ nhận được một mảng của mảng: [[key, value], [key, value]].
Nik Sumeiko

17

Tóm lược:

  • Array.from() , nó nhận một hàm có thể lặp lại như trong đầu vào và trả về một mảng có thể lặp lại.
  • Toán tử Spread: ...kết hợp với một ký tự mảng.

const map = new Map([[ 1, 'one' ],[ 2, 'two' ]]);

const newArr1  = [ ...map  ];  // create an Array literal and use the spread syntax on it
const newArr2 = Array.from( map );  // 

console.log(newArr1, newArr2); 

Cảnh báo khi sao chép mảng:

Hãy nhận thức rằng thông qua các phương pháp trên, chỉ một bản sao cạn được tạo ra khi chúng ta muốn sao chép một mảng. Một ví dụ sẽ làm rõ vấn đề tiềm ẩn:

let arr = [1, 2, ['a', 'b']];

let newArr = [ ...arr ];

console.log(newArr);

arr[2][0] = 'change';

console.log(newArr);

Ở đây vì mảng lồng nhau nên tham chiếu được sao chép và không có mảng mới nào được tạo. Do đó nếu chúng ta thay đổi mảng lồng nhau của mảng cũ, thay đổi này sẽ được phản ánh trong mảng mới (vì chúng tham chiếu đến cùng một mảng, tham chiếu đã được sao chép).

Giải pháp cho cảnh báo:

Chúng tôi có thể giải quyết vấn đề có các bản sao cạn bằng cách sử dụng bản sao sâu của mảng JSON.parse(JSON.stringify(array)). Ví dụ:

let arr = [1, 2, ['a', 'b']]

let newArr = Array.from(arr);

let deepCloneArr = JSON.parse(JSON.stringify(arr));

arr[2][0] = 'change';

console.log(newArr, deepCloneArr)


12

Bạn có thể sử dụng phương thức Array.from , phương thức này đang được thêm vào ES6, nhưng chỉ hỗ trợ các mảng và các đối tượng có thể lặp lại như Maps và Sets (cũng có trong ES6). Đối với các đối tượng thông thường, bạn có thể sử dụng phương thức toArray của Underscore hoặc phương thức toArray của lodash, vì cả hai thư viện thực sự đều hỗ trợ rất tốt cho các đối tượng, không chỉ mảng. Nếu bạn đang sử dụng dấu gạch dưới hoặc dấu gạch ngang, thì may mắn thay, họ có thể xử lý vấn đề cho bạn, cùng với việc thêm các khái niệm chức năng khác nhau như bản đồ và giảm bớt cho các đối tượng của bạn.


3

Phương pháp sau được thử nghiệm cho Maps:

const MyMap = new Map([
  ['a', 1],
  ['b', 2],
  ['c', 3]
]);

const MyArray = [...MyMap].map(item => {
  return {[item[0]]: item[1]}
});

console.info( MyArray ); //[{"a", 1}, {"b", 2}, {"c": 3}]

Không phải những gì được hỏi - xem Array.from way
João Antunes

0
 <<Your_Array>> = [].concat.apply([], Array.from( <<Your_IterableIterator>> ));

-4

Bạn cũng có thể làm:

let arr = [];
for (let elem of gen(...)){
    arr.push(elem);
}

Hoặc "cách khó" sử dụng chức năng tạo ES5 + ( Fiddle hoạt động trong Firefox hiện tại):

var squares = function*(n){
    for (var i=0; i<n; i++){
        yield i*i;
    }
}

var arr = [];
var gen = squares(10);
var g;
while(true){
    g = gen.next();
    if (g.done){
        break;
    }
    arr.push(g.value);
}

Tuy nhiên, cả hai cách tiếp cận chắc chắn không được khuyến khích và chỉ đơn thuần là một bằng chứng về khái niệm.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.