2017-12-22 5 views
1

私はint配列を昇順でソートしており、特定の境界に従って配列の項目をテールから削除したいと思います。私の場合、配列を切り捨てるより良い方法は何ですか?次のコードスニペットを考える:JavaScript - 配列を切り捨てるより効率的な方法

var a = [1, 2, 3, 4]; 
var length = a.length; 
var boundary = 2; 
var count = 0; 
for (var i = length - 1; i >= 0; i--) { 
    if (a[i] > boundary) { 
     a[i] = null; // or delete a[i] ??? 
     count++; 
    } 
} 
a.length -= count; 

、または同じしかしスプライス使用:十分

for (var i = length - 1; i >= 0; i--) { 
    if (a[i] > boundary) { 
     a.splice(i, 1); 
    } 
} 
+1

これら2つのコードスニペットは非常に異なることを行い、どちらもテールだけにある要素を削除しません。私が何を意味するのかを見るには、あなたの配列として '[4、3、2、1]'を使います。 – 4castle

+0

私の配列は常に昇順にソートされます。 – Alex

+1

ああ、私はその細部に気付かなかった。バイナリ検索を使用する必要があります。 – 4castle

答えて

4
a.length -= count; 

厥を;)(長さは、単純なプロパティではなく、ゲッター/セッターないよう要素を切り捨てる/追加する(ref)

スプライス:

a.splice(-count, count); 
+0

理由を説明できますか?フードの下で何が起こっていますか? – Alex

+2

@Alexおそらく 'splice()'と似ていますが、削除された要素の配列を作成する必要はなく、スプライスの後に要素をシフトすることについて心配する必要はありません。 – Barmar

+0

OPの質問を正しく解釈した場合、彼は特に、 'count'要素ではなく'> boundary 'である 'x'テール要素を削除したいと考えています。 'count'は、最初のスニペットでいくつの要素が'> boundary'であったかを追跡するのに使う変数です。 'a.length - = count;'は、削除する要素の数を決定すると、既にそのサンプルで行っていることと同じですが、まだ分かっていません。 – Paulpro

2
現代のエンジンで

、またはシムで、あなたはArray.prototype.findIndexを使用することができます。

var a = [1, 2, 3, 4]; 
 
var boundary = 2; 
 
a.length = a.findIndex(x => x > boundary); 
 
console.log(a);

あなたしている配列がソートされているので、あなたもちょうどArray.prototype.filterを使用することができます。

var a = [1, 2, 3, 4]; 
 
var boundary = 2; 
 
a = a.filter(x => x <= boundary); 
 
console.log(a);

これは、配列が巨大である場合はわずかに(無視できるほど)遅くなる可能性がありますが、古いエンジンではより多くのサポートがあります。

1

配列の最後にある配列エントリを削除して、それを切り捨てないでください。配列エントリを削除すると、まばらな配列を作成することにより、配列からそれらを削除します。配列のlengthプロパティは変更されません:

var a = [1,2,3,4]; 
 
console.log("a.length %s", a.length); 
 
delete a[3]; 
 
console.log("a[3] after deletion: %s", a[3]); 
 
console.log("a.length after deletion %s", a.length); 
 
console.log("a[3] still exists: %s", a.hasOwnProperty("3"));

同様の考察がnullに配列エントリの設定に適用されます。彼らはもはや条件式で真理としてテストされなくなりますが、削除されません。前述のように、配列の長さは変更されません。

配列の長さを既存の値よりも短い値に設定すると、その配列が適切に切り捨てられます。配列を切り捨てる境界位置を見つける方法はたくさんあります。私はあなたに自然に見えるものを選んで、目的のブラウザで動作させることをお勧めします。例えば。ソートされた配列にforSomeを使用すると、あなたの要件を満たしていない可能性があり:)

var a = [1,2,3,4]; 
 
var boundary = 2; 
 
a.some(
 
    (c,i) => { 
 
     if(c > boundary) 
 
     { a.length = i; 
 
     return true; 
 
     } 
 
    } 
 
); 
 

 
console.log(a)

spliceを使用している場合、配列の最後に境界位置からすべてのエントリではなく1回の呼び出しで削除することができることに注意してください

var a = [1,2,3,4]; 
 
var boundary = 2; 
 
for(var i = a.length-1; a[i]>boundary; --i) {} // linear search 
 
a.splice(i+1); 
 
console.log(a);

:それらを一つずつ削除するよりも
関連する問題