2197

Is there a way to empty an array and if so possibly with .remove()?

For instance,

A = [1,2,3,4];

How can I empty that?

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
akano1
  • 35,616
  • 17
  • 46
  • 62

18 Answers18

4855

Ways to clear an existing array A:

Method 1

(this was my original answer to the question)

A = [];

This code will set the variable A to a new empty array. This is perfect if you don't have references to the original array A anywhere else because this actually creates a brand new (empty) array. You should be careful with this method because if you have referenced this array from another variable or property, the original array will remain unchanged. Only use this if you only reference the array by its original variable A.

This is also the fastest solution.

This code sample shows the issue you can encounter when using this method:

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']

Method 2 (as suggested by Matthew Crumley)

A.length = 0

This will clear the existing array by setting its length to 0. Some have argued that this may not work in all implementations of JavaScript, but it turns out that this is not the case. It also works when using "strict mode" in ECMAScript 5 because the length property of an array is a read/write property.

Method 3 (as suggested by Anthony)

A.splice(0,A.length)

Using .splice() will work perfectly, but since the .splice() function will return an array with all the removed items, it will actually return a copy of the original array. Benchmarks suggest that this has no effect on performance whatsoever.

Method 4 (as suggested by tanguy_k)

while(A.length > 0) {
    A.pop();
}

This solution is not very succinct, and it is also the slowest solution, contrary to earlier benchmarks referenced in the original answer.

Performance

Of all the methods of clearing an existing array, methods 2 and 3 are very similar in performance and are a lot faster than method 4. See this benchmark.

As pointed out by Diadistis in their answer below, the original benchmarks that were used to determine the performance of the four methods described above were flawed. The original benchmark reused the cleared array so the second iteration was clearing an array that was already empty.

The following benchmark fixes this flaw: http://jsben.ch/#/hyj65. It clearly shows that methods #2 (length property) and #3 (splice) are the fastest (not counting method #1 which doesn't change the original array).


This has been a hot topic and the cause of a lot of controversy. There are actually many correct answers and because this answer has been marked as the accepted answer for a very long time, I will include all of the methods here. If you vote for this answer, please upvote the other answers that I have referenced as well.

Community
  • 1
  • 1
Philippe Leybaert
  • 155,903
  • 29
  • 200
  • 218
  • 206
    `while (A.length) { A.pop(); }`, no need for `> 0` – Ivan Black Aug 08 '14 at 12:41
  • 369
    `> 0` is more readable IMHO. And there's no performance difference between the two. – Philippe Leybaert Aug 08 '14 at 19:46
  • 2
    var a = [1,2,3]; var b = a; a = []; console.log(b.length); var c = [1,2,3]; var d = c; while(c.length){ c.pop(); } console.log(d.length); – daghan Aug 14 '14 at 13:53
  • 10
    @daghan, it's not at all clear what you're trying to say. `b` holds a reference to the old array even after `a` is assigned a new one. `c` and `d` continue to reference the same array. The difference in outputs is therefore expected. – shovavnik Aug 17 '14 at 08:03
  • I have added the benchmarks for each method, http://jsperf.com/empty-javascript-array. Setting length to 0 is almost always the slowest method, though it is the most readable approach and therefore I suggest using it. – Gajus Sep 30 '14 at 17:38
  • What do you mean by "return copy of the original array *in some (most?) Javascript implementations*."? Shouldn't that be the case in *all* implementations? – moi Oct 01 '14 at 16:37
  • @moi You're right. I'll correct that. On the other hand, a very clever Javascript implementation may decide to inline the function and optimize it in a way that the original array is not being returned if the return value is not used. – Philippe Leybaert Oct 01 '14 at 18:49
  • 3
    Has anybody bothered to *find out* why the completely unintuitive while/pop thing seems to be the fastest in practice? – Matti Virkkunen Oct 20 '14 at 17:49
  • FYI, The method #4 is the fastest in Chrome and IE. In FF and Safari, the first method wins by far. Method #2 is the slowest all the time. – Diego Jancic Nov 06 '14 at 15:17
  • 11
    @DiegoJancic Method #1 doesn't count because it doesn't clear the array. It creates a new one. It shouldn't be included in a benchmark. – Philippe Leybaert Nov 07 '14 at 14:15
  • 1
    @zindigo It does, but it's **5 times slower** than `while(A.length > 0) A.pop();`. See http://jsperf.com/array-destroy/138 – Philippe Leybaert Dec 03 '14 at 14:40
  • @PhilippeLeybaert Interesting I wonder why the compiler doesn't optimize this – Nayeem Zen Dec 03 '14 at 20:27
  • 1
    I wrote the benchmark code and ran it on an Intel(R) Xeon(R) CPU E7- 2850 @ 2.00GHz and 16GB RAM. With x64 v8 3.26 release build, both have identical performance, but running the code using Node, I am able to re-produce while(A.length >0) A.pop(); being significantly better. – Nayeem Zen Dec 03 '14 at 20:54
  • 47
    You can't use `while(A.pop())` in case an item in the array is falsey. Take for example A = [2, 1, 0, -1, -2] would result in A equaling [2, 1]. Even `while(A.pop() !== undefined)` doesn't work because you can have an array with undefined as one of the values. Probably why the compiler doesn't optimized it. – Jonathan Gawrych Jan 09 '15 at 01:29
  • Please include my [answer](http://stackoverflow.com/a/28548360/47401) in your post so everyone can see the actual performance difference between these methods. – Diadistis Feb 16 '15 at 18:55
  • 1
    A.length = 0 also works if the array is read only as in: A: {value: []} – Killroy Apr 16 '15 at 17:00
  • Any loops cost you O(n) – tom10271 Jun 12 '15 at 03:17
  • 1
    @Ivan Black, that's a pretty trivial change. if you're going to do that then you may as well go one step further and remove the curly braces: `while (A.length) A.pop();`, in any case that's not a very performant solution. – Octopus May 04 '16 at 17:08
  • @Octopus, curly braces is the foundation of readability. More than that, `A.length > 0` is more semantically correct (then `A.length`): 77 vs 134. – Ivan Black May 05 '16 at 02:59
  • 1
    A.length = 0; will not work in Typescript. For that, stick to A.splice(0, A.length); – Ryan Loggerythm Jul 09 '16 at 01:31
  • @RyanLoggerythm For normal arrays, the length property is not read-only in Typescript and setting it to 0 will work just fine – Philippe Leybaert Jul 10 '16 at 02:24
  • 2
    Concerning Method 3 : " A.splice(0, A.length) " Is the second parameter really necessary? Wouldn't " A.splice(0) " work the same? – michael.zech Jul 29 '16 at 08:37
  • I also found quite usefull to set variable with array to null and then assign new array like that: `var arr = [a,b,c,d]; arr=null; arr=[]` For me as advantage works that this method forces GC to remove all data storage referenced from removed array (ofc if you don't have any others references to that data). – jazzgot Aug 04 '16 at 15:05
  • 3
    I wish we could just have .clear() method, don't you? The problem with .length = 0; is that there is no good way of knowing how the garbage collector will react to that. The array should still hold references to the other instances, although some magic might have been implemented to manage that. – mmm Aug 15 '16 at 09:49
  • @PhilippeLeybaert Wrong again _" It also works when using "strict mode" in ECMAScript 5 because the length property of an array is a read/write property."_ The "length" of an Array is a full fledged Method of expanding and trimming. Array is like a train, and its index ordered members are just like cabooses of a dragging locomotive. And therefore discarded the same way, by simply detaching at the specified index. And I really wonder where do you get the idea that it wouldn't work on ES5 strict?! – Bekim Bacaj Nov 09 '16 at 11:16
  • @BekimBacaj Are you always this hostile? I added the comment about ECMAScript 5 because there were people who claimed that setting the length doesn't work when using strict mode in ECMAScript 5. – Philippe Leybaert Nov 09 '16 at 19:52
  • @Milos no it doesn't. splice() is not a global function. – Philippe Leybaert Nov 17 '16 at 04:08
  • @PhilippeLeybaert and since when is pointing to your errors and misinformation to be considered hostile - I consider it polite and friendly enough to point to valid information about the OP question from which you will be able to learn and better your understanding. You are saying that `A = [ ]`; is a method that clears the content of the already existing array, which is absolutely untrue. That's assignment of a new empty array literal to an existing variable name. Now that's hostile because it harms you and may cause unexpected errors. – Bekim Bacaj Nov 17 '16 at 08:43
  • @Milos splice() is a global function defined in the library used by jsfiddle. It's not part of Javascript. Try the same in jsbin and you'll see it doesn't work: `splice is not defined` – Philippe Leybaert Nov 18 '16 at 03:54
  • @PhilippeLeybaert I used Method 2 to clear an array and ran into a weird bug. While Method 1 worked perfectly for the same use case. This is what I ended up with (in Google Chrome) while using Method 2: https://pbs.twimg.com/media/C_2L_6nUMAAS6At.jpg:large – lost-and-found May 15 '17 at 06:26
  • 1
    A = [1,2,3]; B = A; both and B will print original array. A = []; This will clear A but not B. A = [1,2,3] ; B = A; A.length = 0; This will clear both A and B. – Girish Gupta Oct 11 '17 at 08:43
  • 1
    So as I understand we can use Method 2 (A.length = 0), because it is fast and easy to write – Gennady G Oct 19 '17 at 09:28
  • setting length to 0 does not work when i have an array of objects – mazs Dec 18 '17 at 12:02
  • @PhilippeLeybaert more readable, perhaps. Less idiomatic to javascript's concepts of truthiness, perhaps. – MrBoJangles Feb 25 '18 at 00:09
  • Method 1 does not clear the array pointed to by A, so it is the wrong answer. – masterxilo Mar 07 '18 at 10:09
  • @mazs, That seems incorrect to me although I may be misunderstanding you. When I create an array of objects, e.g. `const ary = [{a:1},{a:2}];`, then I can clear it by setting length to 0, i.e. `ary.length = 0;`. – Andrew Willems Apr 05 '18 at 02:20
  • @PhilippeLeybaert, perhaps you could include in your answer the following (with working of your choice): As of ES6/2015 all 4 methods will work if `A` is declared with `let` or `var` or is undeclared, i.e. `let A=[3,4]`, `var A=[3,4]` or `A=[3,4]`. However, Method 1 will not work with a variable declared as a constant. For example, `const A = [3,4]; A = [];` will produce `TypeError: Assignment to constant variable` while `const A = [3,4]; A.length = 0;` etc (i.e. Methods 2, 3 & 4) _will_ work. – Andrew Willems Apr 05 '18 at 02:43
  • I'm from the embedded world, and I can't manage to find the `A.length = 0` method better than the `A = []`. In term of process performances, i understand, but what about memory ? How do the garbage collector handle these different methods ? With a lot of heavy arrays, are Methods 2 and 3 still better ? – BuzzRage Apr 12 '18 at 17:07
  • Methods 1 and 2 above should not be used with client side view models such as Vuejs and Knockout. It will break them and they will not detect the change in the array. – Bindrid Apr 16 '18 at 17:22
  • 1
    *A.length = 0* working fine in ECMAScript 6 without strict...:D – ArifMustafa Jul 08 '18 at 01:47
  • 1
    For the non-believers with `A.length = 0`, go to the console : `var A = ["a", [1, 2, 3, 4], 55, { foo: 1, bar: "baz"} ]; var B = A; A.length = 0; B.length = 4; console.log(A); console.log(B);` – Karl Stephen Nov 01 '18 at 02:07
  • @KarlStephen, I didn't understand what you found surprising? You create an array with four items and assigns it to the variables `A` and `B`. Then you empty the (shared) array with `A.length = 0` and after that you set the length of the (still shared) array to 4 with `B.length = 4`. The result is an array with the lenght of 4, containing only undefined items (or nothing depending on how you view it). It is still one single array, referenced with the two variables `A` and `B`. But the array was emptied with the first `A.length = 0` as intended. – Påhl Melin Nov 20 '18 at 11:54
  • 2
    @PåhlMelin : What you said is exactly what's happening, and we both agree. My comment was intended to those who actually don't believe YET that __most if not all modern browsers have managed to make the A.length = 0 the most effective way to empty an array__ : fast, clean, no memory leak, no new array, __and works even if you have other variables references to it__ ! Voilà ! – Karl Stephen Nov 30 '18 at 14:02
  • If array is const the simplest way to remove all items is: `const { items } = this.props; items.splice(0, items.length);` – Jackkobec Feb 02 '19 at 15:18
  • When taking GC into consideration, is there any possibility that `a.length = 0` being faster than `a = []` ? – wyj Jul 08 '19 at 17:33
  • Not safe to use length when an array can hold objects that are not to be taken into account in its length. – Christos Karapapas Oct 20 '19 at 07:54
  • Another funny way to clear the array is , In case of Numeric array , To clear the array using "filter" method . var inputArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]; var max_element = inputArray.reduce(function(a, b) { return Math.max(a, b); }); var filtered = inputArray.filter(function(value, index, arr){ return value > max_element; }); – redhatvicky Nov 13 '19 at 11:20
  • Well looks like indeed pop is a very efficient solution. In Chrome 78, setting length to 0 yields better result than pop, but worse than splice. Surprisingly, in Firefox pop is the fastest solution. – marxin Nov 26 '19 at 14:30
  • I was going to point out that = [] carries a pretty big risk of causing reference bugs and therefore should be avoided at all times. But apparently there's no fast alternative - at least not for large arrays where performance actually matters. It might be the case that setting length = 0 causes immediate garbage collection, so it only appears to be slower. Creating a new reference may be faster in the immediate, simply because the garbage collection of the old instance is deferred to a later point. – Trent May 06 '20 at 04:24
  • 1
    This doesn't actually answer the question. This does not empty the existing array, instead it discards the existing array and replaces it with an empty array, which is not the same thing. – geoidesic May 21 '20 at 09:17
  • This should given given in the answer's **Summary** section to save time for others: 1. `A = []` won't delete at all, `[]` is new array assigned, and old array stays if it has references. 2. We don't want copy given by `A.splice()`. 3. `A.pop()` in a while loop is too slow. 4. So, `A.length = 0` is best. Please update answer @PhilippeLeybaert – Manohar Reddy Poreddy Nov 23 '20 at 02:35
  • If you were worked on Vue and facing reactivity problems, you should use **Method 3:** `A.splice(0,A.length)`. Because Vue monitor value changes by Array's method like push()、pop()、shift()、unshift()、splice()、sort()、reverse(), but the change of `A.length` like `A.length = 0` can not be detected by Vue. – allenyllee Apr 23 '21 at 07:35
  • Object.assign(myOriginalReferencedArray,[]); – Nils Coussement May 21 '21 at 09:51
2556

If you need to keep the original array because you have other references to it that should be updated too, you can clear it without creating a new array by setting its length to zero:

A.length = 0;
alex
  • 438,662
  • 188
  • 837
  • 957
Matthew Crumley
  • 95,375
  • 24
  • 103
  • 125
  • 21
    what does ECMAScript 5 Standard says about this? – Pacerier Jun 21 '11 at 07:00
  • 227
    @Pacerier: It still works in ES5. From section 15.4: "...whenever the length property is changed, every property whose name is an array index whose value is not smaller than the new length is automatically deleted" – Matthew Crumley Jun 21 '11 at 07:43
  • 2
    @einar: JavaScript arrays always expand to fit whatever you put in them, so when you call `myarray.push(whatever)` it adds one to the length. So setting the length truncates the array, but it's not permanent. – Matthew Crumley Oct 05 '11 at 03:53
  • 1
    Would this solution cause/make it possible for a memory leak? Obviously, this depends on the JS interpreter, but it seems like something that could lead to a leak... – Steve Siebert Feb 08 '12 at 20:18
  • 2
    @SteveSiebert It shouldn't in a correctly-implemented interpreter, and I don't know of any implementations that do. OF course, it's possible but it's not any more likely than other incorrect sources of leaks. – Matthew Crumley Feb 08 '12 at 20:28
  • If you use "use strict"; it will not work. Setting a readonly parameter is not allowed. http://stackoverflow.com/questions/1335851/what-does-use-strict-do-in-javascript-and-what-is-the-reasoning-behind-it – LosManos Jan 04 '13 at 11:21
  • 12
    @LosManos Even in strict mode, `length` is a special property, but not read only, so it will still work. – Matthew Crumley Jan 04 '13 at 14:18
  • @MatthewCrumley I tried it in IE10 desktop mode in Win8 - it doesn't work. Can't remember the exact wording of the message - possibly something along the wording of my original comment. – LosManos Jan 06 '13 at 21:36
  • 1
    @LosManos That seems wrong to me. Are you sure it was an array, and not a NodeList or other array-like object? I think the length property would be read only in that case. – Matthew Crumley Jan 07 '13 at 00:18
  • @MatthewCrumley As a serious developer I am not sure without being able to reproduce it and not even then... – LosManos Jan 07 '13 at 11:41
  • 1
    Don't use this approach when creating elements dynamically within for loop(which was my situation).. go with [PhilippeLeybaert](http://stackoverflow.com/a/1232046/1577396) post instead. – Mr_Green Feb 05 '13 at 08:48
  • @VKen does it mean that, it corrects the length automatically? – thefourtheye Aug 19 '13 at 04:42
  • 1
    @VKen Thanks for the reference. So, who will delete the array elements? Garbage collector? – thefourtheye Aug 19 '13 at 12:19
  • 1
    Keep in mind, if you create a new array, the GC will take care of the old one later in time, too! So we can say `arr.length = 0;` = GC immediately and `arr = [];` = GC later on – André Fiedler Oct 06 '13 at 16:21
  • "If you need to keep the original array because you have other references to it that should be updated too," If I don't have any other references, is it still best method ? – Paul Brewczynski Nov 10 '13 at 13:54
  • 12
    @MattewCrumley I done some test, and it seems like a.length = 0 is not to efficient clearing whole array. http://jsperf.com/length-equal-0-or-new-array I think if you have one refence (and you haven't added extra properties that you want to keep), it is better to create new array, and leaves old to the garbage collector, that will run when appropriate. – Paul Brewczynski Nov 16 '13 at 19:08
  • 1
    @HatoruHansou It's not the ***only*** way. The `splice()` and `pop()` methods also don't invalidate other references. – Philippe Leybaert Feb 18 '15 at 19:23
  • @PhilippeLeybaert True, by calling those you do not invalidate the references. I still like length = 0 opposing to ref.splice(0, ref.length) – Hatoru Hansou Feb 18 '15 at 20:56
  • Are we certain that this method of setting the length to 0 gets rid of references to the unwanted array elements? Intuitively, it seems to me that the references are still somewhere inside the array object. They will probably be overwritten by other array elements but it looks like setting it to 0 never really allows the GC to collect the rest and that unwanted memory is blocked from use by everything except the original array. Maybe they have some logic built in for this problem? I'd love for someone to explain. – jollarvia Oct 26 '15 at 12:04
  • 3
    @jollarvia Deleting the elements above the new length is required by the ECMAScript spec, so any correct implementation will make any inaccessible elements garbage collectible. That doesn't necessarily mean they will shrink the storage for the actual array immediately. Specifically, V8 only re-allocates the array if the new length is less than half of the original length, but setting the length to zero essentially re-allocates a new array behind the scenes. – Matthew Crumley Oct 26 '15 at 18:42
  • Yes, the garbage collection issue is exactly why I am in here. To me there is no way of knowing what kind of magic and special logic is executed by setting this value to zero, especially when it is not even a method call. I do not know what the implementors are actually handling it and that's too much magic. I will be popping, and I think it is even faster. Maybe faster than popping is setting each to undefined, so nothing has to be loaded into memory ( return value) . That way I am in control. – mmm Aug 15 '16 at 10:04
  • @momomo Popping elements off the array is likely to have the same effect in terms of memory. There's nothing in the spec that requires implementations to adjust the amount of space allocated to the array, but as far as I know, they will all reduce the size once the length gets below some threshold. – Matthew Crumley Aug 15 '16 at 16:24
  • @momomo (continued) If you want to guarantee the array is as compact as possible at the end, you would need to create a new array and leave the old one to be garbage collected (assuming you're not sharing the array, in which case that's not an option). Whether that's beneficial or not depends on the exact use case. For example, if you're going to be filling in the array again, then reusing the old allocated space would be more efficient and reduce GC pressure. – Matthew Crumley Aug 15 '16 at 16:30
  • @MatthewCrumley You last comment, "the old allocated space would be more efficient and reduce GC pressure." - That's my point, is that .lenght = 0; you do not actually free up the memory. In my use case, I am iterating all elements from first to end, they are functions and once executed they can be removed. Since adjusting the array for each iteration is costly, especially from the beggining to end, I want to clear the array at the end of the iteration of all. I am calling a method with the array to iterate, so setting array = [] won't work. I need to actually empty the array. – mmm Aug 15 '16 at 17:23
  • 1
    .length = 0 does work in my case, but we get back to your comment about garbage collection. I am instead opting for iterating to execute all my functions, and then iterating again to pop after. .length = 0; It would have been better if we would have clear method so folks don't have to get into all kind of issues depending on use case. This entire thread and discussion with over 5000 votes is a testament to that :) – mmm Aug 15 '16 at 17:27
  • how to update it so that it makes the length=0 in all the references? – NeverGiveUp161 May 22 '17 at 10:06
  • @NeverGiveUp161 That's what setting the length already does. Each reference is pointing to the same object in memory, so setting the length on one reference will affect all of them. – Matthew Crumley May 22 '17 at 14:22
  • 1
    In ES6 you want to use `const` instead `var` making the new init less helpful. The `const arr.lenth = 0` is very quick. http://jsben.ch/oZr0V – wnordmann Jul 31 '17 at 18:15
  • setting length to 0 does not work when i have an array of objects – mazs Dec 18 '17 at 12:05
  • 1
    @mazs I'm not sure what you mean. It shouldn't care what type of values are in the array. – Matthew Crumley Dec 18 '17 at 15:46
  • Thanks for getting back to me. I use Typescript and in the meantime I realized that the array what I use has a custom type, thus 0-ing out the length property did not erase the content of the array. I had instead a clear() method. – mazs Dec 19 '17 at 14:14
  • This solution helps with using arrays via Proxy, thanks. – Gaurav Gandhi Jun 25 '19 at 07:21
  • Won't the first method will cause memory leakage? – Blessing Mar 10 '21 at 06:35
  • 1
    @Blessing No, implementations are required to delete the entries at indexes >= the new length, which results in the references no longer existing, leaving any objects free to be garbage-collected (assuming there are no other references). If you do this: `a = [0,1,2]; a.length = 1; console.log(a[2]);`, you'll get undefined, not 2. – Matthew Crumley Mar 15 '21 at 20:15
309

Here the fastest working implementation while keeping the same array ("mutable"):

function clearArray(array) {
  while (array.length) {
    array.pop();
  }
}

FYI it cannot be simplified to while (array.pop()): the tests will fail.

FYI Map and Set define clear(), it would have seem logical to have clear() for Array too.

TypeScript version:

function clearArray<T>(array: T[]) {
  while (array.length) {
    array.pop();
  }
}

The corresponding tests:

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

Here the updated jsPerf: http://jsperf.com/array-destroy/32 http://jsperf.com/array-destroy/152

tanguy_k
  • 8,999
  • 4
  • 46
  • 50
  • 5
    TT your answer is the only one that correct and fast ( at the same time ) but have some much less "upvotes". Well, it seems that people like pretty solutions that are slow :/ – obenjiro Jun 26 '13 at 05:09
  • @naomik But this is one of the basic functionalities, which should have been there by default. – thefourtheye Aug 19 '13 at 04:43
  • 7
    @thefourtheye Good solution for performance, though I agree with @naomik, you should not modify native objects. Saying that it should be there is beside the point, the problem is you're modifying *globals*, which is bad. If you're providing your code for others to use, then it should have no unforeseen side effects. Imagine if another library *also* modified the `Array.prototype` and it was doing something slightly different, then all throughout your code `[].clear()` was slightly wrong. This would not be fun to debug. So, the general message is: Don't modify globals. – jpillora Sep 14 '13 at 10:39
  • @jpillora So what do you suggest? Its okay to add unless there is a function by the name already exists? – thefourtheye Sep 14 '13 at 15:09
  • 3
    @thefourtheye The whole point of not modifying global scope is because *you won't know* if someone else's code is already (or will be) using the name. I suggest a function inside local scope. So, inside your application's/library's [IIFE](http://en.wikipedia.org/wiki/Immediately-invoked_function_expression), do `function clear(arr) { while(arr.length) arr.pop(); }`, then clear arrays with `clear(arr)` instead of `arr.clear()`. – jpillora Sep 15 '13 at 04:58
  • What about memory usage? I read that behind the scenes length=0 is deleting all elements in the array. Is the speed coming with a larger memory cost in this case? 10x – krulik Mar 02 '14 at 22:08
  • I'd say, creating new methods for default objects is perfectly fine as long as it has some unique name. For example, I do so by prepending my nickname to it, and this is not limited with this example. – Utkan Gezer Sep 09 '14 at 00:51
  • [This benchmark](http://jsperf.com/array-destroy/141) moves array population inside each test. Clearing the array quickly with `.pop()` might not be an overall optimization if it slows down creation of the next one. – joeytwiddle Dec 13 '14 at 16:21
  • 2
    It turns out this method is a lot slower than `.splice()` and `.length=0`. The benchmarks were not correct. See my updated answer. – Philippe Leybaert Feb 17 '15 at 01:30
  • @PhilippeLeybaert we should also check the memory occupied before and after each test. And also check that the array is really empty. Anyway, array.length = 0 seems to be the best path. – tanguy_k Feb 17 '15 at 03:46
  • No need for the use of generics in the TypeScript version. The parameter can be just `array: any[]`. – Iván Pérez Jul 24 '19 at 06:41
233

A more cross-browser friendly and more optimal solution will be to use the splice method to empty the content of the array A as below:

A.splice(0, A.length);

JP Richardson
  • 35,950
  • 34
  • 117
  • 150
Anthony
  • 2,451
  • 1
  • 11
  • 2
  • 53
    Why is this more cross-browser friendly? What browsers have issues with A.length? – stricjux Nov 21 '11 at 15:12
  • Like @alex said, `splice` returns a new array. Not something you would want to do in a `REPL`. You could always `void` the expression but that's not an elegant solution. – Aadit M Shah Mar 15 '12 at 14:32
  • 2
    This is the most correct answer since this actually "clears the array content and retains the reference to the original array object. – Shamasis Bhattacharya May 23 '12 at 08:32
  • 4
    @jm2 what you are saying is not entirely true. It actually modifies the array in question and subsequently all references get affected. See the test on my jsFiddle: http://jsfiddle.net/shamasis/dG4PH/ – Shamasis Bhattacharya Sep 26 '12 at 12:38
  • 4
    @alex no it does not, `splice` modifies the array and returns the deleted entries. Read the docs first: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/splice – David Hellsing Oct 29 '12 at 16:22
  • @David Don't know why I wrote that. I must have missed the `p` and confused it with `slice()`. – alex Oct 29 '12 at 23:19
  • 3
    We could prevent the resulting array from being returned by using the [comma operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator): `A.splice(0, A.length),0;`. This would leave a return value of `0` just as `A.length = 0;` would. The resulting array is still created and _should_ cause the script to run slower: ([jsperf](http://jsperf.com/clear-an-array) ~56% slower). Browser implementation will affect this although I see no reason why `splice` would be faster than setting `length`. – Evan Kennedy Aug 18 '13 at 03:47
  • 2
    `splice` is also incredibly slow as compared to other methods http://jsperf.com/array-splice-vs-array-length-0/2 – kumarharsh Jan 10 '14 at 13:55
  • 11
    I have also found that just `A.splice(0)` also works. – corwin.amber Dec 04 '14 at 17:49
  • 1
    @corwin.amber not bad! A.splice(0) comes out 3rd out of the 6 methods! See http://jsben.ch/#/vtDS2 (derived from http://jsben.ch/#/hyj65 - head-to-head with "new init" is here: http://jsben.ch/#/3Do76) – pageman Jan 11 '17 at 08:09
  • 2
    This is defnitely the most "reactivity-friendly" way b/c it's mutable and reactive frameworks (like VUE etc) will be able to "detect" this change and the redraw the UI accordingly – Alex from Jitbit Mar 26 '20 at 22:33
121

The answers that have no less that 2739 upvotes by now are misleading and incorrect.

The question is: "How do you empty your existing array?" E.g. for A = [1,2,3,4].

  1. Saying "A = [] is the answer" is ignorant and absolutely incorrect. [] == [] is false.

    This is because these two arrays are two separate, individual objects, with their own two identities, taking up their own space in the digital world, each on its own.


Let's say your mother asks you to empty the trash can.

  • You don't bring in a new one as if you've done what you've been asked for.
  • Instead, you empty the trash can.
  • You don't replace the filled one with a new empty can, and you don't take the label "A" from the filled can and stick it to the new one as in A = [1,2,3,4]; A = [];

Emptying an array object is the easiest thing ever:

A.length = 0;

This way, the can under "A" is not only empty, but also as clean as new!


  1. Furthermore, you are not required to remove the trash by hand until the can is empty! You were asked to empty the existing one, completely, in one turn, not to pick up the trash until the can gets empty, as in:

    while(A.length > 0) {
        A.pop();
    }
    
  2. Nor, to put your left hand at the bottom of the trash, holding it with your right at the top to be able to pull its content out as in:

    A.splice(0, A.length);
    

No, you were asked to empty it:

A.length = 0;

This is the only code that correctly empties the contents of a given JavaScript array.

MultiplyByZer0
  • 4,341
  • 3
  • 27
  • 46
Bekim Bacaj
  • 4,530
  • 1
  • 19
  • 25
  • 12
    The only problem with your suggested solution is that the trash still exists, it is just that you changed the notice board saying that there is no trash. A reference to the old array should still exist. Can you be sure the garbage collector when setting .length = 0, will also remove all references to the array and its properties ? I think it does though, but to me that is magic. A .clear() method is desirable to avoid confusion to say the least. – mmm Aug 15 '16 at 09:52
  • No sun, that's not true at all. You might wish to test things and understand them deep enough before trying to object something as rock solid as this core JavaScript functionality basics. And it's not "my solution" it's the basic JS syntax since forever. Dubious as it may be `A.length = 0;` is the standard syntax to empty your array. If you wish to have a method such as `A.clear`, you can use this standard syntax to add that method to your arrays easily: `Array.prototype.clear = function(){this.length = 0}`. Have fun. – Bekim Bacaj Aug 15 '16 at 10:51
  • 9
    I never stated that this solution is wrong. The problem is that this entire thread is completely unncessary. Over 3000 votes shows that trying to figure out what the best way is should make it a valid enough case for the EMCA crack head developers to add such a method. Nobody should have to go through figuring it out. There are three - four different ways to do it. In some benchmarks, the length solutions is much slower than others. Furthermore, the idea of setting .length = 0, for any reasonable developer would not be a satisfactory one. – mmm Aug 15 '16 at 14:40
  • 2
    Because to accomplish what it should, all references must be removed. .length = 0 is not even a method call, so if there is other actions taken when it is set to 0 ( which there is in most browsers through define setter ) I would still consider it too magical to actually trust it does what it supposed to do. – mmm Aug 15 '16 at 14:43
  • 7
    Therefore, I'd rather clear it myself. A clear method can be prototyped but that is just ugly. My point is that this implementation should already be present so that over 10 000 developers didn't have to spend hours reading just this thread, not considering all others who spent more time benchmarking. – mmm Aug 15 '16 at 14:47
  • 1
    there's only one way to empty your array fill it with new incoming data and discard it again. All others are either not, or are ridiculously inefficient and unforgivably cpu hungry. The only practical alternative is the `A(n) = A.splice( 0, A.length );` in case you need to backup your previous content. p.s. `Array.length` is a read-write property \ method in case you've missed that basic fact. Meaning, you can expand it to a new length, you cant trim it to whichever length you'd want, and among others you can discard all members by shortening its length to 0. It's a Swiss-knife of the array. – Bekim Bacaj Aug 15 '16 at 18:34
  • @BekimBacaj, upvoted as your answer is by far the nicest and simplest explanation of why solutions other then `A.length = 0` are inappropriate. I wish I could upvote more!! – don Feb 14 '17 at 11:34
  • I agree with ghego1, other answers may be more upvoted, but this one is by far the best, because it explains the whys and whynots. Also, testing (http://jsben.ch/Rh0nb) shows that trusting the browser's internal garbage collection is always better (the splice(0), splice(0,length) and length=0 alternate first places on successive runs). – Cyberknight Feb 01 '18 at 22:02
  • 3
    I loved the metaphors with the real world in this answer. Impressive! – Victor Jul 21 '18 at 21:25
  • ```SPLICE``` is slow https://jsperf.com/empty-javascript-array-redux – Coderboi Nov 09 '19 at 05:21
  • Regarding all the "magic happening behind the scenes" comments: A (maybe) interesting observation is that when setting `.length = 0` there are no delete operations going on, at least not visibly trough a Proxy() `deleteProperty` trap. Normally delete operations performed by mutating array methods like .pop() and the likes will go trough that trap. – exside Sep 21 '20 at 01:38
63

Performance test:

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
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
kenshou.html
  • 892
  • 6
  • 5
  • 9
    Adding the percentage changes arent much use without also noting your platform. On my machine pop is only very mildly quicker in Chrome 34 but actually slower than [] in latest Firefox. – Matt Styles May 15 '14 at 10:56
  • 2
    Testing in Firefox 39.0 32-bit on Windows NT 6.3 64-bit, the a=[] is fastest ! – Reza-S4 Apr 15 '15 at 08:59
  • 1
    of course that creating a new instance of the array is faster than looping and popping it... so if popping is faster in chrome means the creation of a new array creation is buggy – HellBaby Apr 27 '15 at 10:58
  • 5
    There is definitely something fishy in this test result under Chrome. How in hell can the popping loop be that much faster then the other 3 solutions? – chqrlie Jan 30 '16 at 00:48
  • 9
    @chqrlie It's not. It's the slowest method. The benchmark test is flawed. – Philippe Leybaert Nov 17 '16 at 04:13
  • 17
    Please delete this answer as it is wrong, and links to a meaningless flawed test as fake evidence. – James Wakefield May 08 '17 at 05:35
  • the performance results have changed quite a lot over the years - amazing how different the different versions of Chrome seem to be... redefine is the clear performance winner for Chrome 68. (but still does not solve the problem) – gotjosh Aug 26 '18 at 13:03
38

You can add this to your JavaScript file to allow your arrays to be "cleared":

Array.prototype.clear = function() {
    this.splice(0, this.length);
};

Then you can use it like this:

var list = [1, 2, 3];
list.clear();

Or if you want to be sure you don't destroy something:

if (!Array.prototype.clear) {
    Array.prototype.clear = function() {
       this.splice(0, this.length);
    };
}

Lots of people think you shouldn't modify native objects (like Array), and I'm inclined to agree. Please use caution in deciding how to handle this.

leech
  • 7,950
  • 6
  • 60
  • 72
  • 1
    @naomik Can you explain your reasoning why doing such a thing is frowned upon? – Undefined Sep 16 '13 at 16:24
  • 19
    It is "frowned upon" to modify javascript primitive functions like Array and String. You could possibly be overloading an already existing function and trash the object class. There might be an obscure javascript engine that already has clear() and expects it to behave a different way. Tread carefully is all I say. – Design by Adrian Mar 25 '14 at 15:20
  • How about the problem where doing a foreach over the members of an array will suddenly start including a `clear` key? – ErikE Aug 14 '15 at 00:00
  • As a reference: [Why is extending native objects a bad practice?](https://stackoverflow.com/q/14034180/1218980) – Emile Bergeron Sep 12 '17 at 16:03
21

You can easily create a function to do that for you, change the length or even add it to native Array as remove() function for reuse.

Imagine you have this array:

var arr = [1, 2, 3, 4, 5]; //the array

OK, just simply run this:

arr.length = 0; //change the length

and the result is:

[] //result

easy way to empty an array...

Also using loop which is not necessary but just another way to do that:

/* 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(); 
  }
}

There are also tricky way which you can think about, for example something like this:

arr.splice(0, arr.length); //[]

So if arr has 5 items, it will splice 5 items from 0, which means nothing will remain in the array.

Also other ways like simply reassign the array for example:

arr = []; //[]

If you look at the Array functions, there are many other ways to do this, but the most recommended one could be changing the length.

As I said in the first place, you can also prototype remove() as it's the answer to your question. you can simply choose one of the methods above and prototype it to Array object in JavaScript, something like:

Array.prototype.remove = Array.prototype.remove || function() {
  this.splice(0, this.length);
};

and you can simply call it like this to empty any array in your javascript application:

arr.remove(); //[]
Alireza
  • 83,698
  • 19
  • 241
  • 152
19

There is a lot of confusion and misinformation regarding the while;pop/shift performance both in answers and comments. The while/pop solution has (as expected) the worst performance. What's actually happening is that setup runs only once for each sample that runs the snippet in a loop. eg:

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
    }
}

I have created a new test that works correctly :

http://jsperf.com/empty-javascript-array-redux

Warning: even in this version of the test you can't actually see the real difference because cloning the array takes up most of the test time. It still shows that splice is the fastest way to clear the array (not taking [] into consideration because while it is the fastest it's not actually clearing the existing array).

Diadistis
  • 11,727
  • 1
  • 32
  • 54
17
Array.prototype.clear = function() {
    this.length = 0;
};

And call it: array.clear();

Mohammad Usman
  • 30,882
  • 16
  • 80
  • 78
Bendegúz
  • 748
  • 7
  • 15
  • 79
    Please don't encourage modification of the native objects. – Thank you Jul 07 '13 at 06:53
  • 21
    why do people have this tendency to grab the accepted answer and put it into a prototype function? Do you actually do this in your projects? Do you have a huge library of prototype additions that you include in every project? – nurettin Nov 29 '13 at 11:05
  • 4
    Why not just type array.length = 0? – Design by Adrian Mar 25 '14 at 15:24
  • How could this get **any** upvote? No browser I know allows `this = ..`. EDIT: I see, answer was different in previous versions. – Dennis Dec 22 '14 at 13:50
  • @defmx my response would have to come in a long-form answer that has probably been said by hundreds of others. If you're curious, do some googling for "javascript don't modify native" or something. If you still have questions, ask a new question. – Thank you Mar 16 '16 at 18:52
  • 11
    @naomik *"Please don't encourage modification of the native objects."* -- I completely agree with this, but just repeating the sentence by itself comes across as arrogant. Someone proposing such a solution is likely not aware of the consequences, and dropping this line on them instead of providing a short explanation or a link does not convey a meaning other than *"we, people smarter than you, tell you not to do this, because we know better"*. – John Weisz Dec 11 '16 at 11:20
  • 1
    @JohnWhite I actually have answers that give the exact opposite advice, but of course with the added context. It is my responsibility to communicate as effectively as possible, but I'm also okay with being misunderstood. I don't always have the time to provide citations and references for everything I say, and that's okay too. With answers like these (nothing but a snippet of code and zero explanation) I feel obligated to help push in the other direction to let readers know a particular answer doesn't stand unopposed – even if that effort is only slightly greater than the answer. – Thank you Dec 17 '16 at 17:54
  • 6
    As a reference: [Why is extending native objects a bad practice?](https://stackoverflow.com/q/14034180/1218980) – Emile Bergeron Sep 12 '17 at 16:02
  • I don't agree. Adding prototypes to native objects is a bad practice. Look at @EmileBergeron link as to why. – Loligans Feb 14 '18 at 23:48
15

In case you are interested in the memory allocation, you may compare each approach using something like this jsfiddle in conjunction with chrome dev tools' timeline tab. You will want to use the trash bin icon at the bottom to force a garbage collection after 'clearing' the array. This should give you a more definite answer for the browser of your choice. A lot of answers here are old and I wouldn't rely on them but rather test as in @tanguy_k's answer above.

(for an intro to the aforementioned tab you can check out here)

Stackoverflow forces me to copy the jsfiddle so here it is:

<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>

And you should take note that it may depend on the type of the array elements, as javascript manages strings differently than other primitive types, not to mention arrays of objects. The type may affect what happens.

matanster
  • 13,785
  • 14
  • 75
  • 135
14

If you are using

a = []; 

Then you are assigning new array reference to a, if reference in a is already assigned to any other variable, then it will not empty that array too and hence garbage collector will not collect that memory.

For ex.

var a=[1,2,3];
var b=a;
a=[];
console.log(b);// It will print [1,2,3];

or

a.length = 0;

When we specify a.length, we are just resetting boundaries of the array and memory for rest array elements will be connected by garbage collector.

Instead of these two solutions are better.

a.splice(0,a.length)

and

while(a.length > 0) {
    a.pop();
}

As per previous answer by kenshou.html, second method is faster.

Laxmikant Dange
  • 6,983
  • 4
  • 36
  • 60
  • 10
    Apart from being wrong on `a.length`, I don't see what this new answer adds to the thread? – Bergi Dec 01 '14 at 14:33
  • @Bergi I just want to focus about actual memory representation about array – Laxmikant Dange Dec 02 '14 at 09:30
  • Do you have any source to confirm which JS engines will create a new array when `a.length=0;` is performed? How would those engines act for `a.length=500;` and `a.length=4;`? – joeytwiddle Dec 13 '14 at 18:38
  • I tried it on most of browsers, like IE, Firefox, Chrome, it is creating new array. If you set length greater than 0 then it will create an array with undefined elements, i.e. it will just hold some memory locations. – Laxmikant Dange Dec 16 '14 at 15:21
  • 1
    `var a = [1]; var b = a; a.length = 0; console.log(b)` prints `Array [ ]`, so it doesn't seem like it's creating a new array to me. – John Montgomery Sep 15 '17 at 19:10
12

Use a modified version of Jan's initial suggestion:

var originalLength = A.length;
for (var i = originalLength; i > 0; i--) {
     A.pop();
}

Terser:

for (let i = A.length; i > 0;A.pop(),i--) {}

Or here's another take:

while(!A[Symbol.iterator]().next().done)A.shift()
cssimsek
  • 1,179
  • 13
  • 17
  • 13
    Why would you want to do such thing? Why add two more variables and a bunch of code to do the same thing? – klh Sep 14 '14 at 22:51
12

A.splice(0);

I just did this on some code I am working on. It cleared the array.

Louis
  • 128,628
  • 25
  • 249
  • 295
David Campbell
  • 121
  • 1
  • 2
  • No you've just swapped a named array container with a newly created anonymous one. `var A = [1,2,3,4]; var B; B = A.splice(0); console.log(A); console.log(B); ' – Bekim Bacaj Nov 09 '16 at 08:25
9

If you use constants then you have no choice:

const numbers = [1, 2, 3]

You can not reasign:

numbers = []

You can only truncate:

numbers.length = 0
Damjan Pavlica
  • 21,431
  • 6
  • 55
  • 65
6

enter image description here

To Empty a Current memory location of an array use: 'myArray.length = 0' or 'myArray.pop() UN-till its length is 0'

  • length : You can set the length property to truncate an array at any time. When you extend an array by changing its length property, the number of actual elements increases.
  • pop() : The pop method removes the last element from an array and returns that returns the removed value.
  • shift() : The shift method removes the element at the zeroeth index and shifts the values at consecutive indexes down, then returns the removed value.

Example:

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() | [] Create an Array with new memory location by using Array constructor or 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() : By using slice function we get an shallow copy of elements from the original array, with new memory address, So that any modification on cloneArr will not affect to an actual|original array.

    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);
    
Yash
  • 7,342
  • 2
  • 55
  • 63
  • "length : Pops till length of an array is of Specified Size." Who told you this nonsense? – Bekim Bacaj Nov 13 '16 at 11:09
  • @BekimBacaj In essence, it does the same effect. It should probably have said `length = ?` instead of just `length`. – Tuupertunut Jan 09 '17 at 14:53
  • @BekimBacaj i have updated my answer, I just assumed that length pops till length, but i corrected now that length just truncates or increases the size of an array. – Yash Nov 29 '17 at 12:57
4

I'm surprised no one has suggested this yet:

let xs = [1,2,3,4];
for (let i in xs)
    delete xs[i];

This yields an array in quite a different state from the other solutions. In a sense, the array has been 'emptied':

xs
=> Array [ <4 empty slots> ]

[...xs]
=> Array [ undefined, undefined, undefined, undefined ]

xs.length
=> 4

xs[0]
=> ReferenceError: reference to undefined property xs[0]

You can produce an equivalent array with [,,,,] or Array(4)

Cauterite
  • 1,391
  • 14
  • 21
  • 7
    It could be a good answer to a different question: "How to convert all elements in an array to undefined elements". – Ruben Mar 25 '17 at 18:54
  • Though internally there is a difference between undefined elements and empty slots ("holes") – Cauterite Aug 23 '19 at 04:59
-10

Use below if you need to empty Angular 2+ FormArray.

public emptyFormArray(formArray:FormArray) {
    for (let i = formArray.controls.length - 1; i >= 0; i--) {
        formArray.removeAt(i);
    }
}
Manish Jain
  • 8,990
  • 5
  • 35
  • 39