Khởi tạo một mảng với một giá trị duy nhất


Câu trả lời:


44
while(arraySize--) array.push(value);

không có khởi tạo (mà tôi biết)


Cập nhật

Kể từ khi đăng câu trả lời này 4 năm trước, mọi người dường như tiếp tục quay lại đây để tìm câu trả lời này. Đối với mục đích đo điểm chuẩn, tôi đã tạo một JSPerf với một số giải pháp khác nhau.

Giải pháp ở trên đây không phải là nhanh nhất, mặc dù nó ngắn. Để duy trì cùng một phong cách ngắn nhưng với hiệu suất tốt hơn:

while(size--) array[size] = value;

Cập nhật tháng 2 năm 2016 Đã cập nhật JSPerf với một bản sửa đổi mới với nhiều tủ thử nghiệm hơn.

Nếu hiệu suất không quan trọng và bạn muốn có một lớp lót:

var value = 1234, // can be replaced by a fixed value
    size  = 1000, // can be replaced by a fixed value
    array = Array.apply(null,{length: size}).map(function() { return value; });

Một giải pháp hiệu quả hơn (trong một, bẩn, dòng): Lưu ý: điều này thay thế các biến giá trị, kích thước và i đang tồn tại trong phạm vi

for(var i = 0, value = 1234, size = 1000, array = new Array(1000); i < size; i++) array[i] = value;

Trong nhiều trường hợp, “arraySize” sẽ không thể thay đổi được (có thể là một hằng số hoặc theo nghĩa đen hoặc - tôi biết, thực hành không tốt - “array.length”). Bằng cách biểu diễn kích thước dưới dạng một biến, tôi đã làm cho điều này không rõ ràng.
oldlivingboy

1
true: "for (var i = arraySize; i--;) array.push (value);" sau đó :-) nhưng tôi nghĩ rằng bạn figured mà ra đã
DoXicK

1
Bạn nói đúng - cú pháp đó loại bỏ năm ký tự. ;-)
oldlivingboy 29/10/10

3
whilechậm hơn 2 lần so với forJavaScript và các kiểm tra đơn giản như if (number)cũng chậm hơn if (number === 0)do chuyển đổi kiểu (điều này cũng áp dụng cho boolean, string và null). Các bài kiểm tra jsPerf của tôi đã dạy tôi điều này.
Triang3l

2
new Array (len) .fill (0);
Muhammad Umer

135

Một cách ngắn gọn để làm điều đó sẽ là:

var arr = Array(arraySize).fill(value);

Ví dụ sẽ tạo arr = Array [ 0, 0, 0, 0, 0 ]if arraySize == 5value == 0.



23
@Perry. Bạn biết đấy, khi trình duyệt chiếm 6% thị trường không hỗ trợ tiêu chuẩn thì đó là vấn đề của trình duyệt đó
Slava

12
Hãy cẩn thận với hàm điền nếu giá trị là một đối tượng, vì bạn có thể có cùng một đối tượng trong toàn bộ mảng, điều này có thể gây ra kết quả không mong muốn.
Gregzenegair

9

OP dường như hướng đến sự nhỏ gọn trong kịch bản sử dụng một lần hơn là hiệu quả và khả năng tái sử dụng. Đối với những người khác đang tìm kiếm hiệu quả, đây là cách tối ưu hóa chưa được đề cập. Vì bạn biết trước độ dài của mảng, hãy tiếp tục và đặt nó trước khi gán các giá trị. Nếu không, mảng sẽ được thay đổi kích thước liên tục - không lý tưởng!

function initArray(length, value) {
    var arr = [], i = 0;
    arr.length = length;
    while (i < length) { arr[i++] = value; }
    return arr;
}

var data = initArray(1000000, false);

1
Trong JavaScript, fornhanh hơn gấp 2 lần while.
Triang3l

2
Tôi sẽ không nói rằng nó là chính xác như: stoimen.com/blog/2012/01/24/javascript-performance-for-vs-while Chắc chắn bạn sẽ không muốn luôn luôn sử dụng một trong hai độc quyền - đó là đánh bại mục đích của họ. Công việc của thông dịch viên / trình biên dịch là tăng tốc độ nó ở nơi nó có thể, không phải của bạn. Nhưng ngay cả điều đó không phải lúc nào cũng đúng.
Aram Kocharyan

9

Điều này không nhỏ gọn nhưng được cho là trực tiếp hơn.

array = Array.apply(null, new Array(arraySize)).map(function () {return value;});

5

Điều này có thể không tốt hơn bất kỳ kỹ thuật nào ở trên nhưng nó rất thú vị ...

var a = new Array(10).join('0').split('').map(function(e) {return parseInt(e, 10);})

Bạn có thể giải thích tại sao var arr = (new Array(5)).map(() => 1);không hoạt động?
Bharat Gupta

1
Phương thức map () chỉ hoạt động trên các giá trị trong mảng. Nó bỏ qua các phần tử không xác định.
Christopher Weiss

Vì vậy, sau new Array(5)khi chúng ta lập bản đồ, chúng ta có đang hoạt động trên một mảng không? Ngoài ra, điều này [1,undefined,3].map(() => 5)hoạt động như mong đợi. Nó không bỏ quaundefined
Bharat Gupta

2
Từ tài liệu mozilla tại developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… : map gọi một hàm gọi lại được cung cấp một lần cho mỗi phần tử trong một mảng, theo thứ tự và tạo một mảng mới từ kết quả . gọi lại chỉ được gọi cho các chỉ mục của mảng có các giá trị được gán, bao gồm cả không xác định. Nó không được gọi cho các phần tử bị thiếu của mảng (nghĩa là các chỉ mục chưa bao giờ được đặt, đã bị xóa hoặc chưa bao giờ được gán giá trị).
Christopher Weiss

Tuyệt vời. Cảm ơn @Christopher!
Bharat Gupta

4

Đây là một câu hỏi cũ, nhưng tôi sử dụng câu này trong JS hiện đại:

[...new Array(1000000)].map(()=>42);

2

Để có hiệu quả, tôi sẽ tránh push. Rất dễ

for (var i = 0; i < arraySize; i++) array[i] = value; 

Đối với IE10:

array = new Array(arraySize); 
for (var i = 0; i < arraySize; i++) array[i] = value; 

Chỉnh sửa: sửa đổi như đã thảo luận trong các ý kiến.


for (var i = 0; i < arraySize; ++i)có hiệu suất gần như tương tự như mã của bạn, nhưng trông gọn gàng hơn. Nhưng while (arraySize--)chậm hơn 2 lần.
Triang3l

Có, nhưng phân bổ bộ nhớ cho arrayhiệu quả hơn là bắt đầu array[0].
Kyaw Tun

2
Không. Nếu bạn bắt đầu khởi tạo một mảng từ cuối, bảng băm sẽ được sử dụng trong nội bộ, nhưng nếu bạn bắt đầu khởi tạo một mảng từ 0 và bạn chỉ có các chỉ số tuần tự, một mảng thực sẽ được sử dụng (ít nhất là trong V8). JavaScript không phân bổ các phần tử (chỉ số cao nhất + 1), nó chỉ phân bổ các phần tử được khởi tạo.
Triang3l 29/10/12

Từ cuộc thảo luận [Build / 12] ( channel9.msdn.com/Events/Build/2012/4-000 ), IE10 cần phân bổ trước để hoạt động hiệu quả. Tham khảo [trên Trang trình bày 54] ( channel9.msdn.com/Events/Build/2012/4-000 )
Kyaw Tun

1

Nếu bạn cần thực hiện nhiều lần, bạn luôn có thể viết một hàm:

function makeArray(howMany, value){
    var output = [];
    while(howMany--){
        output.push(value);
    }
    return output;
}

var data = makeArray(40, "Foo");

Và, chỉ để hoàn thiện (loay hoay với nguyên mẫu của các đối tượng tích hợp thường không phải là một ý kiến ​​hay):

Array.prototype.fill = function(howMany, value){
    while(howMany--){
        this.push(value);
    }
}

Vì vậy, bây giờ bạn có thể:

var data = [];
data.fill(40, "Foo");

Cập nhật: Tôi vừa xem ghi chú của bạn về arraySize là một hằng số hoặc theo nghĩa đen. Nếu vậy, chỉ cần thay thế tất cả while(howMany--)bằng cũ tốt for(var i=0; i<howMany; i++).


1

Tình cờ gặp cái này trong khi khám phá các phương thức mảng trên máy bay .. ohhh những nơi chúng tôi đến khi chúng tôi cảm thấy buồn chán. :)

var initializedArray = new Array(30).join(null).split(null).map(function(item, index){
  return index;
});

.map()null để giành chiến thắng! Tôi thích null vì việc chuyển vào một chuỗi như lên trên cùng với '0' hoặc bất kỳ giá trị nào khác là khó hiểu. Tôi nghĩ điều này rõ ràng hơn rằng chúng tôi đang làm một điều gì đó khác biệt.

Lưu ý rằng .map()bỏ qua các giá trị không được khởi tạo. Đây là lý do tại sao new Array(30).map(function(item, index){return index});không hoạt động. .fill()Phương pháp mới được ưu tiên nếu có, tuy nhiên cần lưu ý hỗ trợ trình duyệt kể từ ngày 23 tháng 8 năm 2015 .

Máy tính để bàn (Hỗ trợ cơ bản)

  • Chrome 45 (36 1 )
  • Firefox (Gecko) 31 (31)
  • Internet Explorer không được hỗ trợ
  • Opera không được hỗ trợ
  • Safari 7.1

Từ MDN :

[1, 2, 3].fill(4);               // [4, 4, 4]
[1, 2, 3].fill(4, 1);            // [1, 4, 4]
[1, 2, 3].fill(4, 1, 2);         // [1, 4, 3]
[1, 2, 3].fill(4, 1, 1);         // [1, 2, 3]
[1, 2, 3].fill(4, -3, -2);       // [4, 2, 3]
[1, 2, 3].fill(4, NaN, NaN);     // [1, 2, 3]
Array(3).fill(4);                // [4, 4, 4]
[].fill.call({ length: 3 }, 4);  // {0: 4, 1: 4, 2: 4, length: 3}

Điều này có thể hiện nay (tháng 6 năm 2019) một cách dễ dàng được viết như sau: [...Array(30)].map((_, i) => i);
magikMaker
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.