JavaScriptの配列から特定の要素を削除するにはどうすればよいですか?


Answers

私はarray.remove(int)がどのように動作することを期待しているのか分かりません。 あなたが欲しいかもしれないと考えることができる3つの可能性があります。

インデックスi配列の要素を削除するには:

array.splice(i, 1);

numberを持つすべての要素を配列から削除する場合は、次のようにします。

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

インデックスの要素をもう作成しないようにしたいが、他の要素のインデックスを変更したくない場合は、次のようにします。

delete array[i];
Question

私は整数の配列を持っており、要素を追加するために.push()メソッドを使用しています。

配列から特定の要素を削除する簡単な方法はありますか? array.remove(int);ようなものに相当しarray.remove(int);

コア JavaScriptを使用する必要があります。フレームワークは使用できません




lodash _.pull (mutate array)、 _.pullAt_.pullAt array)または_.without_.pullAt array)を使用することができます。

var array1 = ['a', 'b', 'c', 'd']
_.pull(array1, 'c')
console.log(array1) // ['a', 'b', 'd']

var array2 = ['e', 'f', 'g', 'h']
_.pullAt(array2, 0)
console.log(array2) // ['f', 'g', 'h']

var array3 = ['i', 'j', 'k', 'l']
var newArray = _.without(array3, 'i') // ['j', 'k', 'l']
console.log(array3) // ['i', 'j', 'k', 'l']



新しい配列を作成する:

var my_array = new Array();

この配列に要素を追加する:

my_array.push("element1");

関数indexOf(インデックスを返すか、見つからなければ-1):

var indexOf = function(needle) 
{
    if(typeof Array.prototype.indexOf === 'function') // newer browsers
    {
        indexOf = Array.prototype.indexOf;
    } 
    else // older browsers
    {
        indexOf = function(needle) 
        {
            var index = -1;

            for(var i = 0; i < this.length; i++) 
            {
                if(this[i] === needle) 
                {
                    index = i;
                    break;
                }
            }
            return index;
        };
    }

    return indexOf.call(this, needle);
};

この要素のインデックスを調べる(firefoxとIE8 +でテスト済み):

var index = indexOf.call(my_array, "element1");

配列からインデックスにある1要素を削除する

my_array.splice(index, 1);



John Resig は良い実装を投稿しました

// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};

グローバルオブジェクトを拡張したくない場合は、代わりに次のようなことができます。

// Array Remove - By John Resig (MIT Licensed)
Array.remove = function(array, from, to) {
    var rest = array.slice((to || from) + 1 || array.length);
    array.length = from < 0 ? array.length + from : from;
    return array.push.apply(array, rest);
};

しかし、私がこれを投稿する主な理由は、そのページのコメント(2007年12月14日)で提案されている代替実装に対してユーザーに警告することです。

Array.prototype.remove = function(from, to){
  this.splice(from, (to=[0,from||1,++to-from][arguments.length])<0?this.length+to:to);
  return this.length;
};

最初はうまくいくようですが、痛いプロセスを通して、配列内の最後から2番目の要素を削除しようとすると失敗することが分かりました。 たとえば、10要素の配列があり、これで9番目の要素を削除しようとすると、次のようになります。

myArray.remove(8);

最終的に8要素配列になります。 理由を知らないけど、私はジョンのオリジナルの実装にこの問題がないことを確認しました。




あなたが空の場所を保持したいかどうかによって異なります。

空のスロットが必要な場合は、削除しても問題ありません。

delete array[ index ];

そうでない場合は、 spliceメソッドを使用する必要があります。

array.splice( index, 1 );

そしてその項目の値が必要な場合は、返された配列の要素を格納するだけです:

var value = array.splice( index, 1 )[0];

あなたが何らかの順序でそれをしたい場合は、最後のものはarray.shift() 、最初のものはarray.pop()を使うことができます。

また、項目のインデックスがわからない場合は、 array.indexOf( item )を使用して取得できます( if()項目を取得するか、 while()すべて取得する)。 array.indexOf( item )はインデックスを返します。見つからなければ-1を返します。




より現代的なECMAScript 2015 (旧ハーモニーまたはES 6)アプローチ。 与えられた:

const items = [1, 2, 3, 4];
const index = 2;

次に:

items.filter((x, i) => i !== index);

収穫:

[1, 2, 4]

Babelpolyfillサービスを使用して、これがブラウザ間で十分にサポートされていることを確認できます。




主に2つのアプローチがあります。

  1. スプライス()anArray.splice(index, 1);

  2. 削除delete anArray[index];

配列に対してdeleteを使用する場合は注意が必要です。 オブジェクトの属性を削除するのには良いが、配列にはあまり適していない。 アレイにspliceを使用する方が良いです。

配列に対してdeleteを使用deleteと、 anArray.length結果が間違っている可能性があることに注意してanArray.length 。 つまり、 deleteは要素を削除しますが、lengthプロパティの値は更新しません。

また、削除を使用した後にインデックス番号に穴を開けることを期待することもできます。たとえば、削除を使用する前にインデックス1,3,4,8,9,11およびlengthを持つことになります。 その場合、索引はもはや逐次的ではないので、索引付けされたforループはすべてクラッシュします。

あなたが何らかの理由でdeleteを使用deleteことを余儀なくされた場合は、配列をループする必要があるときにfor eachループfor each使用する必要があります。 実際には、可能であれば、インデックス付きforループを使用しないでください。 そうすれば、コードはより堅牢になり、インデックスの問題を起こしにくくなります。




配列に複雑なオブジェクトがある場合、フィルタを使用できますか? $ .inArrayまたはarray.spliceが使いやすくない場合。 特にオブジェクトが配列内で浅い場合は特にそうです。

たとえば、Idフィールドを持つオブジェクトがあり、そのオブジェクトを配列から削除する場合は、次のようにします。

this.array = this.array.filter(function(element, i) {
    return element.id !== idToRemove;
});



削除された位置が削除された新しい配列が必要な場合は、特定の要素を削除して配列を除外することができます。 フィルターメソッドを実装していないブラウザーでは、 配列オブジェクトの拡張が必要な​​場合がありますが、長期的には、これだけ簡単です。

var my_array = [1,2,3,4,5,6];
delete my_array[4];
console.log(my_array.filter(function(a){return typeof a !== 'undefined';}));

[1, 2, 3, 4, 6] 1、2、3、4、6]と表示されます[1, 2, 3, 4, 6]




インデックスで削除

インデックスの要素を持たない配列のコピーを返す関数。

/**
* removeByIndex
* @param {Array} array
* @param {Number} index
*/
function removeByIndex(array, index){
    return array.filter(function(elem, _index){
        return index != _index;
    });
}
l = [1,3,4,5,6,7];
console.log(removeByIndex(l, 1));

$> [ 1, 4, 5, 6, 7 ]

値で削除

値のない配列のコピーを返す関数。

/**
* removeByValue
* @param {Array} array
* @param {Number} value
*/
function removeByValue(array, value){
    return array.filter(function(elem, _index){
        return value != elem;
    });
}
l = [1,3,4,5,6,7];
console.log(removeByValue(l, 5));

$> [ 1, 3, 4, 6, 7]



filterメソッドで簡単に行うことができます:

function remove(arrOriginal, elementToRemove){
    return arrOriginal.filter(function(el){return el !== elementToRemove});
}
console.log( remove([1, 2, 1, 0, 3, 1, 4], 1) );

これにより、配列からすべての要素が削除され、スライスとインデックスの組み合わせが速くなります。




indexOfまたはspliceを使用する必要はありません。 ただし、要素の1つのオカレンスだけを削除したい場合は、より効果的です。

検索して移動する(移動する):

function move(arr, val) {
  var j = 0;
  for (var i = 0, l = arr.length; i < l; i++) {
    if (arr[i] !== val) {
      arr[j++] = arr[i];
    }
  }
  arr.length = j;
}

indexOfsplice (indexof)を使用してください:

function indexof(arr, val) {
  var i;
  while ((i = arr.indexOf(val)) != -1) {
    arr.splice(i, 1);
  }
}

splice (スプライス)のみを使用してください:

function splice(arr, val) {
  for (var i = arr.length; i--;) {
    if (arr[i] === val) {
      arr.splice(i, 1);
    }
  }
}

1000要素(平均10000回の実行)の配列に対するnodejsの実行時間:

indexof移動より約10倍遅い。 スプライス内のindexOfへの呼び出しを削除することで改善されたとしても、 移動よりもはるかに悪い動作をします。

Remove all occurrences:
    move 0.0048 ms
    indexof 0.0463 ms
    splice 0.0359 ms

Remove first occurrence:
    move_one 0.0041 ms
    indexof_one 0.0021 ms



私はJavaScriptを使い慣れていないので、この機能が必要でした。 私は単にこれを書いた:

function removeFromArray(array, item, index) {
  while((index = array.indexOf(item)) > -1) {
    array.splice(index, 1);
  }
}

それから私がそれを使いたいとき:

//Set-up some dummy data
var dummyObj = {name:"meow"};
var dummyArray = [dummyObj, "item1", "item1", "item2"];

//Remove the dummy data
removeFromArray(dummyArray, dummyObj);
removeFromArray(dummyArray, "item2");

出力 - 期待どおり。 ["item1"、 "item1"]

あなたは私とは違ったニーズを持っているかもしれないので、簡単に修正することができます。 私はこれが誰かを助けることを望む。




私は既に多くの回答があることを知っていますが、その多くは問題を複雑にするようです。 ここでは、キーのすべてのインスタンスを削除するシンプルで再帰的な方法があります。インデックスが見つからない限り、selfを呼び出します。 はい、それはindexOf持つブラウザでのみ機能しますが、シンプルで簡単にポリ充てることができます。

スタンドアロン機能

function removeAll(array, key){
    var index = array.indexOf(key);

    if(index === -1) return;

    array.splice(index, 1);
    removeAll(array,key);
}

プロトタイプ法

Array.prototype.removeAll = function(key){
    var index = this.indexOf(key);

    if(index === -1) return;

    this.splice(index, 1);
    this.removeAll(key);
}



2017-05-08

Most of the given answers work for strict comparison, meaning that both objects reference the exact same object in memory (or are primitive types), but often you want to remove a non-primitive object from an array that has a certain value. For instance, if you make a call to a server and want to check a retrieved object against a local object.

const a = {'field': 2} // Non-primitive object
const b = {'field': 2} // Non-primitive object with same value
const c = a            // Non-primitive object that reference the same object as "a"

assert(a !== b) // Don't reference the same item, but have same value
assert(a === c) // Do reference the same item, and have same value (naturally)

//Note: there are many alternative implementations for valuesAreEqual
function valuesAreEqual (x, y) {
   return  JSON.stringify(x) === JSON.stringify(y)
}


//filter will delete false values
//Thus, we want to return "false" if the item
// we want to delete is equal to the item in the array
function removeFromArray(arr, toDelete){
    return arr.filter(target => {return !valuesAreEqual(toDelete, target)})
}

const exampleArray = [a, b, b, c, a, {'field': 2}, {'field': 90}];
const resultArray = removeFromArray(exampleArray, a);

//resultArray = [{'field':90}]

There are alternative/faster implementations for valuesAreEqual, but this does the job. You can also use a custom comparator if you have a specific field to check (for example, some retrieved UUID vs a local UUID).

Also note that this is a functional operation, meaning that it does not mutate the original array.