回答:
既存の配列をクリアする方法A
:
方法1
(これは質問に対する私の元の答えでした)
A = [];
このコードは、変数A
を新しい空の配列に設定します。これは、元の配列への参照がA
他にない場合に最適です。これは、実際に新しい(空の)配列を作成するためです。別の変数またはプロパティからこの配列を参照した場合、元の配列は変更されないため、このメソッドには注意する必要があります。これを使用するのは、元の変数で配列を参照する場合のみですA
。
これも最速のソリューションです。
このコードサンプルは、このメソッドを使用するときに発生する可能性がある問題を示しています。
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']
方法2(Matthew Crumleyの提案による)
A.length = 0
これにより、長さを0に設定することで既存の配列がクリアされます。JavaScriptのすべての実装ではこれが機能しない可能性があると主張する人もいますが、そうではないことがわかりました。配列のlengthプロパティは読み取り/書き込みプロパティであるため、ECMAScript 5で「strictモード」を使用する場合にも機能します。
A.splice(0,A.length)
を使用.splice()
すると完全に.splice()
機能しますが、関数は削除されたすべての項目を含む配列を返すため、実際には元の配列のコピーが返されます。ベンチマークは、これがパフォーマンスにまったく影響しないことを示唆しています。
while(A.length > 0) {
A.pop();
}
このソリューションは非常に簡潔ではなく、最初の回答で参照された以前のベンチマークとは異なり、最も遅いソリューションでもあります。
パフォーマンス
既存のアレイをクリアするすべての方法のうち、方法2と3はパフォーマンスが非常によく似ており、方法4よりもはるかに高速です。このベンチマークを参照してください。
Diadistisが以下の回答で指摘しているように、上記の4つの方法のパフォーマンスを決定するために使用された元のベンチマークには欠陥がありました。元のベンチマークは、クリアされた配列を再利用したため、2回目の反復では、すでに空の配列がクリアされていました。
次のベンチマークはこの欠陥を修正します:http : //jsben.ch/#/hyj65。メソッド#2(長さプロパティ)と#3(スプライス)が最速であることを明確に示しています(元の配列を変更しないメソッド#1はカウントしません)。
これはホットな話題であり、多くの論争の原因となっています。実際には多くの正解がありますが、この回答は非常に長い間、受け入れられた回答としてマークされているため、ここではすべての方法を取り上げます。この回答に投票する場合は、私が参照した他の回答にも投票してください。
while (A.length) { A.pop(); }
、必要なし> 0
> 0
より読みやすい私見です。また、2つの間にパフォーマンスの違いはありません。
b
配列a
が割り当てられた後でも、古い配列への参照を保持します。同じ配列c
をd
引き続き参照します。したがって、出力の違いが予想されます。
while(A.pop())
配列の項目が誤っている場合は使用できません。たとえば、A = [2、1、0、-1、-2]の場合、Aは[2、1]になります。でも、while(A.pop() !== undefined)
あなたが値の一つとして、未定義の配列を持つことができるので、動作しません。おそらくコンパイラが最適化していないのでしょう。
更新する必要がある他の参照があるために元の配列を保持する必要がある場合は、その長さをゼロに設定することにより、新しい配列を作成せずに配列をクリアできます。
A.length = 0;
myarray.push(whatever)
と長さが1加算されます。したがって、長さを設定すると配列が切り捨てられますが、永続的なものではありません。
length
特別なプロパティですが、読み取り専用ではないため、引き続き機能します。
ここで、同じ配列(「可変」)を維持しながら、最も速く機能する実装:
function clearArray(array) {
while (array.length) {
array.pop();
}
}
参考までに、これを単純化することはできませwhile (array.pop())
ん。テストは失敗します。
参考までに、MapとSetの定義clear()
ではclear()
、Arrayについても同様に論理的に考えられます。
TypeScriptバージョン:
function clearArray<T>(array: T[]) {
while (array.length) {
array.pop();
}
}
対応するテスト:
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);
});
});
ここで更新されたjsPerf:http : //jsperf.com/array-destroy/32 http://jsperf.com/array-destroy/152
Array.prototype
、それがわずかに異なる何かを行っていたとしたら、コード全体[].clear()
が少し間違っていたとします。これはデバッグするのが楽しくありません。したがって、一般的なメッセージは次のとおりです。グローバルを変更しないでください。
function clear(arr) { while(arr.length) arr.pop(); }
、clear(arr)
ではなくで配列をクリアしますarr.clear()
。
.splice()
して.length=0
。ベンチマークは正しくありませんでした。私の更新された答えを見てください。
よりブラウザーに適した、より最適なソリューションはsplice
、以下のようにメソッドを使用して配列Aのコンテンツを空にすることです。
A.splice(0, A.length);
splice
変更しません。配列を変更し、削除したエントリを返します。最初のドキュメントを読む:developer.mozilla.org/en-US/docs/JavaScript/Reference/...を
A.splice(0)
うまくいくことも発見しました。
現在2739票以上の回答は誤解を招くものであり、正しくありません。
問題は、「既存のアレイをどのように空にするか」です。たとえばA = [1,2,3,4]
。
「A = []
答えはそれだ」と言うのは無知でまったく間違いです。[] == []
はfalseです。
これは、これら2つの配列が2つの個別の個別のオブジェクトであり、独自の2つのIDを持ち、デジタルの世界で独自の空間を占有しているためです。
母親がゴミ箱を空にするように頼んだとしましょう。
A = [1,2,3,4]; A = [];
配列オブジェクトを空にすることは、これまでで最も簡単なことです。
A.length = 0;
このように、「A」の下の缶は空であるだけでなく、新品同様にきれいです!
さらに、缶が空になるまで手でゴミを取り除く必要はありません!次の例のように、缶が空になるまでゴミを拾わないように、既存のものを完全に空にするように求められました。
while(A.length > 0) {
A.pop();
}
また、左手をゴミ箱の底に置き、右手を上にして持ち、次のようにコンテンツを引き出すことができます。
A.splice(0, A.length);
いいえ、空にするように求められました:
A.length = 0;
これは、特定のJavaScript配列のコンテンツを正しく空にする唯一のコードです。
A(n) = A.splice( 0, A.length );
以前のコンテンツをバックアップする必要がある場合です。ps Array.length
は、その基本的な事実を見逃した場合の読み取り/書き込みプロパティ\メソッドです。つまり、新しい長さに拡張したり、好きな長さにトリミングしたりできません。また、長さを0に短くすることで、すべてのメンバーを破棄できます。これは、配列のスイスナイフです。
性能試験:
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
これをJavaScriptファイルに追加して、配列を「クリア」できるようにすることができます。
Array.prototype.clear = function() {
this.splice(0, this.length);
};
その後、次のように使用できます。
var list = [1, 2, 3];
list.clear();
または、何かを破壊しないようにしたい場合:
if (!Array.prototype.clear) {
Array.prototype.clear = function() {
this.splice(0, this.length);
};
}
多くの人が、ネイティブオブジェクト(配列など)を変更するべきではないと考えています。私は同意する傾向があります。これを処理する方法を決定する際には注意してください。
clear
キーが含まれるようになるという問題はどうですか?
回答とコメントの両方で、while; pop / shiftパフォーマンスに関する多くの混乱と誤った情報があります。while / popソリューションは(予想どおり)最悪のパフォーマンスを示します。実際に起こっていることは、ループでスニペットを実行するサンプルごとに1回だけセットアップが実行されることです。例えば:
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
}
}
私は正しく機能する新しいテストを作成しました:
http://jsperf.com/empty-javascript-array-redux
警告:このバージョンのテストでも、アレイのクローンを作成するのにほとんどのテスト時間がかかるため、実際の違いはわかりません。それはまだそれがsplice
配列をクリアする最も速い方法であることを示しています([]
これは最速ですが実際には既存の配列をクリアしないため、考慮していません)。
メモリの割り当てに関心がある場合は、このjsfiddleのようなものをChrome開発ツールのタイムラインタブと組み合わせて使用して、各アプローチを比較できます。アレイを「クリア」した後、下部のごみ箱アイコンを使用してガベージコレクションを強制することができます。これにより、選択したブラウザに対してより明確な答えが得られます。ここでの回答の多くは古く、私はそれらに依存するのではなく、上記の@tanguy_kの回答のようにテストします。
Stackoverflowは私にjsfiddleをコピーすることを強制するので、ここにあります:
<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>
オブジェクトの配列は言うまでもなく、JavaScriptは他のプリミティブ型とは異なる方法で文字列を管理するため、配列要素の型に依存する可能性があることに注意してください。タイプは、何が起こるかに影響を与える可能性があります。
これを行う関数を簡単に作成したり、長さを変更したり、再利用する関数としてネイティブ配列に追加したりすることもできremove()
ます。
次の配列があるとします。
var arr = [1, 2, 3, 4, 5]; //the array
OK、単にこれを実行してください:
arr.length = 0; //change the length
結果は次のとおりです。
[] //result
配列を空にする簡単な方法...
また、必要ではないがそれを行う別の方法であるループを使用する:
/* 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();
}
}
あなたが考えることができるトリッキーな方法もあります、例えばこのようなもの:
arr.splice(0, arr.length); //[]
したがって、arrに5つのアイテムがある場合、0から5つのアイテムを接合します。これは、配列に何も残っていないことを意味します。
また、たとえば配列を単に再割り当てするような他の方法:
arr = []; //[]
配列関数を見ると、他にも多くの方法がありますが、最も推奨される方法は長さを変更することです。
最初に言ったように、あなたの質問に対する答えであるため、remove()のプロトタイプを作成することもできます。上記のメソッドの1つを選択して、JavaScriptでArrayオブジェクトにプロトタイプを作成するだけです。
Array.prototype.remove = Array.prototype.remove || function() {
this.splice(0, this.length);
};
そしてあなたは単にあなたのJavaScriptアプリケーションの任意の配列を空にするためにこのようにそれを呼び出すことができます:
arr.remove(); //[]
Array.prototype.clear = function() {
this.length = 0;
};
そしてそれを呼び出す: array.clear();
A.splice(0);
私が取り組んでいるいくつかのコードでこれを実行しました。アレイをクリアしました。
使用している場合
a = [];
次に、aに新しい配列参照を割り当てます。aの参照がすでに他の変数に割り当てられている場合、その配列も空にならず、ガベージコレクターがそのメモリを収集しません。
例のために。
var a=[1,2,3];
var b=a;
a=[];
console.log(b);// It will print [1,2,3];
または
a.length = 0;
を指定するa.length
と、配列の境界をリセットするだけで、残りの配列要素のメモリはガベージコレクターによって接続されます。
これらの2つのソリューションの代わりに優れています。
a.splice(0,a.length)
そして
while(a.length > 0) {
a.pop();
}
kenshou.htmlによる以前の回答のとおり、2番目の方法の方が高速です。
a.length
、この新しい答えがスレッドに追加するものはわかりませんか?
a.length=0;
実行時に新しいJSエンジンが新しいアレイを作成することを確認するためのソースはありますか?どのようにそれらのエンジンは、のために行動するだろうa.length=500;
とa.length=4;
?
var a = [1]; var b = a; a.length = 0; console.log(b)
prints Array [ ]
なので、新しい配列を作成しているようには見えません。
定数を使用する場合、選択肢はありません。
const numbers = [1, 2, 3]
再署名できません:
numbers = []
切り捨てることしかできません:
numbers.length = 0
配列の現在のメモリ位置を空にするには、以下を使用します:'myArray.length = 0'
または'myArray.pop() UN-till its length is 0'
length
:lengthプロパティを設定して、いつでも配列を切り捨てることができます。lengthプロパティを変更して配列を拡張すると、実際の要素の数が増加します。pop()
:popメソッドは配列から最後の要素を削除し、削除された値を返すを返します。shift()
:shiftメソッドは、0番目のインデックスの要素を削除し、連続するインデックスの値を下にシフトして、削除された値を返します。例:
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() | []
Array constructor
またはを使用して、新しいメモリ位置で配列を作成します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()
:スライス関数を使用して、元の配列から要素の浅いコピーを取得し、新しいメモリアドレスを指定します。これにより、cloneArrを変更しても実際の配列には影響しません。
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 = ?
だけではなく言ったほうがいいでしょうlength
。
まだ誰もこれを提案していないことに驚いています:
let xs = [1,2,3,4];
for (let i in xs)
delete xs[i];
これにより、他のソリューションとはかなり異なる状態のアレイが生成されます。ある意味で、配列は「空」になっています。
xs
=> Array [ <4 empty slots> ]
[...xs]
=> Array [ undefined, undefined, undefined, undefined ]
xs.length
=> 4
xs[0]
=> ReferenceError: reference to undefined property xs[0]
[,,,,]
またはで同等の配列を作成できますArray(4)
Angular 2+ FormArrayを空にする必要がある場合は、以下を使用してください。
public emptyFormArray(formArray:FormArray) {
for (let i = formArray.controls.length - 1; i >= 0; i--) {
formArray.removeAt(i);
}
}