Câu trả lời:
Các cách để xóa một mảng hiện có A
:
Phương pháp 1
(đây là câu trả lời ban đầu của tôi cho câu hỏi)
A = [];
Mã này sẽ đặt biến A
thành một mảng trống mới. Điều này là hoàn hảo nếu bạn không có tham chiếu đến mảng ban đầu ởA
bất kỳ nơi nào khác bởi vì điều này thực sự tạo ra một mảng hoàn toàn mới (trống). Bạn nên cẩn thận với phương thức này bởi vì nếu bạn đã tham chiếu mảng này từ một biến hoặc thuộc tính khác, thì mảng ban đầu sẽ không thay đổi. Chỉ sử dụng điều này nếu bạn chỉ tham chiếu mảng theo biến ban đầu của nó A
.
Đây cũng là giải pháp nhanh nhất.
Mẫu mã này cho thấy vấn đề bạn có thể gặp phải khi sử dụng phương pháp này:
var arr1 = ['a','b','c','d','e','f'];
var arr2 = arr1; // Reference arr1 by another variable
arr1 = [];
console.log(arr2); // Output ['a','b','c','d','e','f']
Phương pháp 2 (theo đề xuất của Matthew Crumley )
A.length = 0
Điều này sẽ xóa mảng hiện có bằng cách đặt độ dài của nó thành 0. Một số người đã lập luận rằng điều này có thể không hoạt động trong tất cả các triển khai JavaScript, nhưng hóa ra đây không phải là trường hợp. Nó cũng hoạt động khi sử dụng "chế độ nghiêm ngặt" trong ECMAScript 5 vì thuộc tính độ dài của một mảng là thuộc tính đọc / ghi.
Phương pháp 3 (theo đề xuất của Anthony )
A.splice(0,A.length)
Việc sử dụng .splice()
sẽ hoạt động hoàn hảo, nhưng vì .splice()
hàm sẽ trả về một mảng với tất cả các mục bị loại bỏ, nên nó thực sự sẽ trả về một bản sao của mảng ban đầu. Điểm chuẩn cho thấy điều này không ảnh hưởng gì đến hiệu suất.
Phương pháp 4 (theo đề xuất của tanguy_k )
while(A.length > 0) {
A.pop();
}
Giải pháp này không ngắn gọn lắm, và nó cũng là giải pháp chậm nhất, trái với các điểm chuẩn trước đó được tham chiếu trong câu trả lời ban đầu.
Hiệu suất
Trong tất cả các phương pháp xóa một mảng hiện có , phương thức 2 và 3 có hiệu suất rất giống nhau và nhanh hơn rất nhiều so với phương pháp 4. Xem điểm chuẩn này .
Như Diadistis đã chỉ ra trong câu trả lời của họ dưới đây, các điểm chuẩn ban đầu được sử dụng để xác định hiệu suất của bốn phương pháp được mô tả ở trên là thiếu sót. Điểm chuẩn ban đầu đã sử dụng lại mảng đã xóa để lần lặp thứ hai đang xóa một mảng đã trống.
Điểm chuẩn sau sửa lỗi này: http://jsben.ch/#/hyj65 . Nó cho thấy rõ rằng các phương thức # 2 (thuộc tính độ dài) và # 3 (mối nối) là nhanh nhất (không tính phương thức số 1 không thay đổi mảng ban đầu).
Đây là một chủ đề nóng và là nguyên nhân của rất nhiều tranh cãi. Thực tế có rất nhiều câu trả lời đúng và vì câu trả lời này đã được đánh dấu là câu trả lời được chấp nhận trong một thời gian rất dài, tôi sẽ bao gồm tất cả các phương pháp ở đây. Nếu bạn bỏ phiếu cho câu trả lời này, vui lòng nêu lên các câu trả lời khác mà tôi đã tham khảo.
while (A.length) { A.pop(); }
, không cần> 0
> 0
IMHO dễ đọc hơn. Và không có sự khác biệt hiệu suất giữa hai.
b
giữ một tham chiếu đến mảng cũ ngay cả sau khi a
được gán một mảng mới. c
và d
tiếp tục tham chiếu cùng một mảng. Do đó, sự khác biệt trong đầu ra được mong đợi.
while(A.pop())
trong trường hợp một mục trong mảng là falsey. Lấy ví dụ A = [2, 1, 0, -1, -2] sẽ dẫn đến A bằng [2, 1]. Thậm chí while(A.pop() !== undefined)
không hoạt động vì bạn có thể có một mảng với không xác định là một trong các giá trị. Có lẽ tại sao trình biên dịch không tối ưu hóa nó.
Nếu bạn cần giữ mảng ban đầu vì bạn cũng có các tham chiếu khác đến mảng đó, bạn có thể xóa nó mà không cần tạo một mảng mới bằng cách đặt độ dài của nó thành 0:
A.length = 0;
myarray.push(whatever)
nó sẽ thêm một chiều dài. Vì vậy, thiết lập độ dài cắt ngắn mảng, nhưng nó không vĩnh viễn.
length
là một thuộc tính đặc biệt, nhưng không chỉ đọc, vì vậy nó sẽ vẫn hoạt động.
Ở đây triển khai làm việc nhanh nhất trong khi vẫn giữ cùng một mảng ("có thể thay đổi"):
function clearArray(array) {
while (array.length) {
array.pop();
}
}
FYI không thể đơn giản hóa thành while (array.pop())
: các bài kiểm tra sẽ thất bại.
Bản đồ FYI và Set xác định clear()
, nó cũng có vẻ hợp lý clear()
đối với Array .
Phiên bản TypeScript:
function clearArray<T>(array: T[]) {
while (array.length) {
array.pop();
}
}
Các xét nghiệm tương ứng:
describe('clearArray()', () => {
test('clear regular array', () => {
const array = [1, 2, 3, 4, 5];
clearArray(array);
expect(array.length).toEqual(0);
expect(array[0]).toEqual(undefined);
expect(array[4]).toEqual(undefined);
});
test('clear array that contains undefined and null', () => {
const array = [1, undefined, 3, null, 5];
clearArray(array);
expect(array.length).toEqual(0);
expect(array[0]).toEqual(undefined);
expect(array[4]).toEqual(undefined);
});
});
Tại đây jsPerf được cập nhật: http://jsperf.com/array-destroy/32 http://jsperf.com/array-destroy/152
Array.prototype
và nó đang làm một cái gì đó hơi khác, thì tất cả mã của bạn [].clear()
đều hơi sai. Điều này sẽ không vui để gỡ lỗi. Vì vậy, thông điệp chung là: Đừng sửa đổi toàn cầu.
function clear(arr) { while(arr.length) arr.pop(); }
, sau đó xóa các mảng clear(arr)
thay vì arr.clear()
.
.splice()
và .length=0
. Các điểm chuẩn không chính xác. Xem câu trả lời cập nhật của tôi.
Một giải pháp thân thiện hơn và tối ưu hơn cho trình duyệt sẽ là sử dụng splice
phương thức để làm trống nội dung của mảng A như dưới đây:
A.splice(0, A.length);
splice
sửa đổi mảng và trả về các mục đã xóa. Đọc tài liệu trước: developer.mozilla.org/en-US/docs/JavaScript/Reference/
A.splice(0, A.length),0;
. Điều này sẽ để lại một giá trị trả lại 0
như là A.length = 0;
sẽ. Mảng kết quả vẫn được tạo và sẽ khiến tập lệnh chạy chậm hơn: ( jsperf ~ 56% chậm hơn). Việc thực hiện trình duyệt sẽ ảnh hưởng đến điều này mặc dù tôi thấy không có lý do tại sao splice
sẽ nhanh hơn cài đặt length
.
A.splice(0)
làm việc.
Các câu trả lời mà không ít hơn 2739 upvote cho đến nay là sai lệch và không chính xác.
Câu hỏi là: "Làm thế nào để bạn làm trống mảng hiện tại của bạn?" Ví dụ cho A = [1,2,3,4]
.
Nói " A = []
là câu trả lời" là không biết gì và hoàn toàn không chính xác. [] == []
là sai .
Điều này là do hai mảng này là hai đối tượng riêng biệt, riêng biệt, với hai danh tính riêng, chiếm không gian riêng trong thế giới kỹ thuật số, mỗi đối tượng riêng.
Hãy nói rằng mẹ của bạn yêu cầu bạn đổ thùng rác.
A = [1,2,3,4]; A = [];
Làm trống một đối tượng mảng là điều dễ nhất từng có:
A.length = 0;
Bằng cách này, lon dưới chữ "A" không chỉ trống mà còn sạch như mới!
Hơn nữa, bạn không cần phải loại bỏ rác bằng tay cho đến khi lon rỗng! Bạn được yêu cầu dọn sạch cái hiện có, hoàn toàn, trong một lượt, không được nhặt rác cho đến khi có thể để trống, như trong:
while(A.length > 0) {
A.pop();
}
Cũng không, để đặt tay trái của bạn ở dưới cùng của thùng rác, giữ nó bằng tay phải của bạn ở trên cùng để có thể kéo nội dung của nó ra như trong:
A.splice(0, A.length);
Không, bạn được yêu cầu làm trống nó:
A.length = 0;
Đây là mã duy nhất làm trống chính xác nội dung của một mảng JavaScript nhất định.
A(n) = A.splice( 0, A.length );
trong trường hợp bạn cần sao lưu nội dung trước đó. ps Array.length
là một thuộc tính đọc-ghi \ trong trường hợp bạn bỏ lỡ thực tế cơ bản đó. Có nghĩa là, bạn có thể mở rộng nó sang một độ dài mới, bạn không thể cắt nó theo bất kỳ độ dài nào bạn muốn và trong số những người khác bạn có thể loại bỏ tất cả các thành viên bằng cách rút ngắn độ dài của nó xuống 0. Đó là một con dao Thụy Sĩ của mảng.
Kiểm tra hiệu suất:
http://jsperf.com/array-clear-methods/3
a = []; // 37% slower
a.length = 0; // 89% slower
a.splice(0, a.length) // 97% slower
while (a.length > 0) {
a.pop();
} // Fastest
Bạn có thể thêm phần này vào tệp JavaScript của mình để cho phép các mảng của bạn được "xóa":
Array.prototype.clear = function() {
this.splice(0, this.length);
};
Sau đó, bạn có thể sử dụng nó như thế này:
var list = [1, 2, 3];
list.clear();
Hoặc nếu bạn muốn chắc chắn rằng bạn không phá hủy thứ gì đó:
if (!Array.prototype.clear) {
Array.prototype.clear = function() {
this.splice(0, this.length);
};
}
Nhiều người nghĩ rằng bạn không nên sửa đổi các đối tượng gốc (như Array) và tôi có xu hướng đồng ý. Hãy thận trọng trong việc quyết định làm thế nào để xử lý này.
clear
khóa?
Có rất nhiều nhầm lẫn và thông tin sai lệch trong khi đó, hiệu suất pop / shift cả trong câu trả lời và nhận xét. Giải pháp while / pop có hiệu suất kém nhất . Điều thực sự xảy ra là thiết lập chỉ chạy một lần cho mỗi mẫu chạy đoạn mã trong một vòng lặp. ví dụ:
var arr = [];
for (var i = 0; i < 100; i++) {
arr.push(Math.random());
}
for (var j = 0; j < 1000; j++) {
while (arr.length > 0) {
arr.pop(); // this executes 100 times, not 100000
}
}
Tôi đã tạo một thử nghiệm mới hoạt động chính xác:
http://jsperf.com/empty-javascript-array-redux
Cảnh báo: ngay cả trong phiên bản thử nghiệm này, bạn thực sự không thể thấy sự khác biệt thực sự bởi vì nhân bản mảng chiếm phần lớn thời gian thử nghiệm. Nó vẫn chỉ ra rằng đó splice
là cách nhanh nhất để xóa mảng (không []
xem xét bởi vì trong khi đó là cách nhanh nhất thì nó không thực sự xóa mảng hiện có).
Trong trường hợp bạn quan tâm đến việc cấp phát bộ nhớ, bạn có thể so sánh từng cách tiếp cận bằng cách sử dụng thứ gì đó như jsfiddle này kết hợp với tab dòng thời gian của công cụ chrome dev. Bạn sẽ muốn sử dụng biểu tượng thùng rác ở phía dưới để buộc bộ sưu tập rác sau khi 'xóa' mảng. Điều này sẽ cung cấp cho bạn một câu trả lời chắc chắn hơn cho trình duyệt bạn chọn. Rất nhiều câu trả lời ở đây đã cũ và tôi sẽ không dựa vào chúng mà chỉ kiểm tra như trong câu trả lời của @ tanguy_k ở trên.
(đối với phần giới thiệu về tab đã nói ở trên, bạn có thể xem tại đây )
Stackoverflow buộc tôi phải sao chép jsfiddle vì vậy đây là:
<html>
<script>
var size = 1000*100
window.onload = function() {
document.getElementById("quantifier").value = size
}
function scaffold()
{
console.log("processing Scaffold...");
a = new Array
}
function start()
{
size = document.getElementById("quantifier").value
console.log("Starting... quantifier is " + size);
console.log("starting test")
for (i=0; i<size; i++){
a[i]="something"
}
console.log("done...")
}
function tearDown()
{
console.log("processing teardown");
a.length=0
}
</script>
<body>
<span style="color:green;">Quantifier:</span>
<input id="quantifier" style="color:green;" type="text"></input>
<button onclick="scaffold()">Scaffold</button>
<button onclick="start()">Start</button>
<button onclick="tearDown()">Clean</button>
<br/>
</body>
</html>
Và bạn nên lưu ý rằng nó có thể phụ thuộc vào loại của các thành phần mảng, vì javascript quản lý các chuỗi khác với các kiểu nguyên thủy khác, không đề cập đến các mảng của các đối tượng. Các loại có thể ảnh hưởng đến những gì xảy ra.
Bạn có thể dễ dàng tạo một hàm để làm điều đó cho bạn, thay đổi độ dài hoặc thậm chí thêm nó vào Mảng bản địa dưới dạng remove()
hàm để sử dụng lại.
Hãy tưởng tượng bạn có mảng này:
var arr = [1, 2, 3, 4, 5]; //the array
OK, chỉ đơn giản là chạy này:
arr.length = 0; //change the length
và kết quả là:
[] //result
cách dễ dàng để làm trống một mảng ...
Cũng sử dụng vòng lặp không cần thiết mà chỉ là một cách khác để làm điều đó:
/* could be arr.pop() or arr.splice(0)
don't need to return as main array get changed */
function remove(arr) {
while(arr.length) {
arr.shift();
}
}
Cũng có những cách khó khăn mà bạn có thể nghĩ đến, ví dụ như một cái gì đó như thế này:
arr.splice(0, arr.length); //[]
Vì vậy, nếu mảng có 5 mục, nó sẽ ghép 5 mục từ 0, có nghĩa là không có gì còn lại trong mảng.
Ngoài ra các cách khác như chỉ đơn giản là gán lại mảng chẳng hạn:
arr = []; //[]
Nếu bạn nhìn vào các hàm Array, có nhiều cách khác để làm điều này, nhưng cách được khuyên dùng nhất có thể là thay đổi độ dài.
Như tôi đã nói ở nơi đầu tiên, bạn cũng có thể xóa nguyên mẫu () vì đó là câu trả lời cho câu hỏi của bạn. bạn có thể chỉ cần chọn một trong các phương thức ở trên và tạo nguyên mẫu cho đối tượng Array trong JavaScript, đại loại như:
Array.prototype.remove = Array.prototype.remove || function() {
this.splice(0, this.length);
};
và bạn có thể chỉ cần gọi nó như thế này để làm trống bất kỳ mảng nào trong ứng dụng javascript của bạn:
arr.remove(); //[]
Array.prototype.clear = function() {
this.length = 0;
};
Và gọi nó là: array.clear();
A.splice(0);
Tôi chỉ làm điều này trên một số mã tôi đang làm việc. Nó xóa mảng.
Nếu bạn đang sử dụng
a = [];
Sau đó, bạn đang gán tham chiếu mảng mới cho a, nếu tham chiếu trong a đã được gán cho bất kỳ biến nào khác, thì nó cũng sẽ không làm trống mảng đó và do đó trình thu gom rác sẽ không thu thập bộ nhớ đó.
Dành cho người cũ
var a=[1,2,3];
var b=a;
a=[];
console.log(b);// It will print [1,2,3];
hoặc là
a.length = 0;
Khi chúng tôi chỉ định a.length
, chúng tôi chỉ đặt lại ranh giới của mảng và bộ nhớ cho các phần tử mảng còn lại sẽ được kết nối bởi trình thu gom rác.
Thay vì hai giải pháp này là tốt hơn.
a.splice(0,a.length)
và
while(a.length > 0) {
a.pop();
}
Theo câu trả lời trước của kenshou.html, phương pháp thứ hai nhanh hơn.
a.length
, tôi không thấy câu trả lời mới này thêm vào chủ đề gì?
a.length=0;
được thực hiện không? Làm thế nào những động cơ sẽ hành động cho a.length=500;
và a.length=4;
?
var a = [1]; var b = a; a.length = 0; console.log(b)
bản in Array [ ]
, vì vậy có vẻ như nó không tạo ra một mảng mới cho tôi.
Nếu bạn sử dụng hằng số thì bạn không có lựa chọn nào:
const numbers = [1, 2, 3]
Bạn không thể sắp xếp lại:
numbers = []
Bạn chỉ có thể cắt ngắn:
numbers.length = 0
Để làm trống một vị trí bộ nhớ hiện tại của một mảng, hãy sử dụng: 'myArray.length = 0'
hoặc'myArray.pop() UN-till its length is 0'
length
: Bạn có thể đặt thuộc tính độ dài để cắt một mảng bất cứ lúc nào. Khi bạn mở rộng một mảng bằng cách thay đổi thuộc tính độ dài của nó, số lượng phần tử thực tế tăng lên.pop()
: Phương thức pop loại bỏ phần tử cuối cùng khỏi một mảng và trả về giá trị bị loại bỏ.shift()
: Phương thức shift loại bỏ phần tử tại chỉ mục zeroeth và dịch chuyển các giá trị ở các chỉ mục liên tiếp xuống, sau đó trả về giá trị bị loại bỏ.Thí dụ:
var arr = ['77'];
arr.length = 20;
console.log("Increasing : ", arr); // (20) ["77", empty × 19]
arr.length = 12;
console.log("Truncating : ", arr); // (12) ["77", empty × 11]
var mainArr = new Array();
mainArr = ['1', '2', '3', '4'];
var refArr = mainArr;
console.log('Current', mainArr, 'Refered', refArr);
refArr.length = 3;
console.log('Length: ~ Current', mainArr, 'Refered', refArr);
mainArr.push('0');
console.log('Push to the End of Current Array Memory Location \n~ Current', mainArr, 'Refered', refArr);
mainArr.poptill_length(0);
console.log('Empty Array \n~ Current', mainArr, 'Refered', refArr);
Array.prototype.poptill_length = function (e) {
while (this.length) {
if( this.length == e ) break;
console.log('removed last element:', this.pop());
}
};
new Array() | []
Tạo một mảng với vị trí bộ nhớ mới bằng cách sử dụng Array constructor
hoặc array literal
.
mainArr = []; // a new empty array is addressed to mainArr.
var arr = new Array('10'); // Array constructor
arr.unshift('1'); // add to the front
arr.push('15'); // add to the end
console.log("After Adding : ", arr); // ["1", "10", "15"]
arr.pop(); // remove from the end
arr.shift(); // remove from the front
console.log("After Removing : ", arr); // ["10"]
var arrLit = ['14', '17'];
console.log("array literal « ", indexedItem( arrLit ) ); // {0,14}{1,17}
function indexedItem( arr ) {
var indexedStr = "";
arr.forEach(function(item, index, array) {
indexedStr += "{"+index+","+item+"}";
console.log(item, index);
});
return indexedStr;
}
slice()
: Bằng cách sử dụng hàm lát, chúng tôi nhận được một bản sao nông của các phần tử từ mảng ban đầu, với địa chỉ bộ nhớ mới, do đó, bất kỳ sửa đổi nào trên cloneArr sẽ không ảnh hưởng đến một mảng thực tế | ban đầu.
var shallowCopy = mainArr.slice(); // this is how to make a copy
var cloneArr = mainArr.slice(0, 3);
console.log('Main', mainArr, '\tCloned', cloneArr);
cloneArr.length = 0; // Clears current memory location of an array.
console.log('Main', mainArr, '\tCloned', cloneArr);
length = ?
thay vì chỉ length
.
Tôi ngạc nhiên không ai đề nghị điều này chưa:
let xs = [1,2,3,4];
for (let i in xs)
delete xs[i];
Điều này mang lại một mảng ở trạng thái khá khác với các giải pháp khác. Theo một nghĩa nào đó, mảng đã bị 'làm trống':
xs
=> Array [ <4 empty slots> ]
[...xs]
=> Array [ undefined, undefined, undefined, undefined ]
xs.length
=> 4
xs[0]
=> ReferenceError: reference to undefined property xs[0]
Bạn có thể tạo một mảng tương đương với [,,,,]
hoặcArray(4)
Sử dụng bên dưới nếu bạn cần làm trống Angular 2+ FormArray.
public emptyFormArray(formArray:FormArray) {
for (let i = formArray.controls.length - 1; i >= 0; i--) {
formArray.removeAt(i);
}
}