私はそれらが別の配列に存在する場合、JavaScriptの配列からすべての要素を削除するための効率的な方法を探しています。
// If I have this array:
var myArray = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
// and this one:
var toRemove = ['b', 'c', 'g'];
MyArrayをこの状態のままにしておきます。['a', 'd', 'e', 'f']
JQueryでは、grep()
とinArray()
を使っています。
myArray = $.grep(myArray, function(value) {
return $.inArray(value, toRemove) < 0;
});
ループや接続をせずにこれを行うための純粋なJavaScriptの方法はありますか?
Array.filter()
メソッドを使います。
myArray = myArray.filter( function( el ) {
return toRemove.indexOf( el ) < 0;
} );
ブラウザが Array.includes()
をサポートするようになり、小さな改良が行われました。
myArray = myArray.filter( function( el ) {
return !toRemove.includes( el );
} );
矢印機能 を使った次の適応
myArray = myArray.filter( ( el ) => !toRemove.includes( el ) );
filter
メソッドがうまくいくはずです:
const myArray = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
const toRemove = ['b', 'c', 'g'];
// ES5 syntax
const filteredArray = myArray.filter(function(x) {
return toRemove.indexOf(x) < 0;
});
toRemove
配列が大きい場合、この種の検索パターンは非効率的になる可能性があります。ルックアップがO(1)
ではなくO(n)
になるようにマップを作成する方がパフォーマンスが上がります。
const toRemoveMap = toRemove.reduce(
function(memo, item) {
memo[item] = memo[item] || true;
return memo;
},
{} // initialize an empty object
);
const filteredArray = myArray.filter(function (x) {
return toRemoveMap[x];
});
// or, if you want to use ES6-style arrow syntax:
const toRemoveMap = toRemove.reduce((memo, item) => ({
...memo,
[item]: true
}), {});
const filteredArray = myArray.filter(x => toRemoveMap[x]);
あなたがオブジェクトの配列を使用している場合。それから、以下のコードは魔法をするべきです、そこで、オブジェクトの特性は重複したアイテムを取り除くための基準になるでしょう。
以下の例では、各項目の名前を比較して重複が削除されています。
この例を試してください。 http://jsfiddle.net/deepak7641/zLj133rh/
var myArray = [
{name: 'deepak', place: 'bangalore'},
{name: 'chirag', place: 'bangalore'},
{name: 'alok', place: 'berhampur'},
{name: 'chandan', place: 'mumbai'}
];
var toRemove = [
{name: 'deepak', place: 'bangalore'},
{name: 'alok', place: 'berhampur'}
];
for( var i=myArray.length - 1; i>=0; i--){
for( var j=0; j<toRemove.length; j++){
if(myArray[i] && (myArray[i].name === toRemove[j].name)){
myArray.splice(i, 1);
}
}
}
alert(JSON.stringify(myArray));
Lodashにもこのためのユーティリティ機能があります。 https://lodash.com/docs#difference
ECMAScript 6セット は、2つの配列の異なる要素を計算するために使用できます。
const myArray = new Set(['a', 'b', 'c', 'd', 'e', 'f', 'g']);
const toRemove = new Set(['b', 'c', 'g']);
const difference = new Set([...myArray].filter((x) => !toRemove.has(x)));
console.log(Array.from(difference)); // ["a", "d", "e", "f"]
私はちょうど次のように実装しました:
Array.prototype.exclude = function(list){
return this.filter(function(el){return list.indexOf(el)<0;})
}
使用:
myArray.exclude(toRemove);
あなたがfilter
のような新しいES5のものを使うことができないなら、私はあなたが2つのループで立ち往生していると思う:
for( var i =myArray.length - 1; i>=0; i--){
for( var j=0; j<toRemove.length; j++){
if(myArray[i] === toRemove[j]){
myArray.splice(i, 1);
}
}
}
ワンライナー風味で:
console.log(['a', 'b', 'c', 'd', 'e', 'f', 'g'].filter(x => !~['b', 'c', 'g'].indexOf(x)))
古いブラウザでは動作しないかもしれません。
Lodashから _。differenceBy を使用できます。
const myArray = [
{name: 'deepak', place: 'bangalore'},
{name: 'chirag', place: 'bangalore'},
{name: 'alok', place: 'berhampur'},
{name: 'chandan', place: 'mumbai'}
];
const toRemove = [
{name: 'deepak', place: 'bangalore'},
{name: 'alok', place: 'berhampur'}
];
const sorted = _.differenceBy(myArray, toRemove, 'name');
ここでのコード例: CodePen
できるだけ簡単な方法はどうですか:
var myArray = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
var toRemove = ['b', 'c', 'g'];
var myArray = myArray.filter((item) => !toRemove.includes(item));
console.log(myArray)
別の配列に含まれるすべての要素を削除するための適切な方法は、要素のみを削除することによってソース配列を同じオブジェクトにすることです。
Array.prototype.removeContained = function(array) {
var i, results;
i = this.length;
results = [];
while (i--) {
if (array.indexOf(this[i]) !== -1) {
results.Push(this.splice(i, 1));
}
}
return results;
};
あるいはCoffeeScriptの同等物:
Array.prototype.removeContained = (array) ->
i = @length
@splice i, 1 while i-- when array.indexOf(@[i]) isnt -1
Chrome devツール内でテストする:
19:33:04.447 a = 1
19:33:06.354 b = 2
19:33:07.615 c = 3
19:33:09.981 arr = [a、b、c]
19:33:16.460 arr1 = arr19:33:20.317 arr1 === arr
19:33:20.331真19:33:43.592 arr.removeContained([a、c])
19:33:52.433 arr === arr1
19:33:52.438 真
大量のウォッチャーやリロードを行わずにコレクションを更新する場合は、Angularフレームワークを使用するのがソースオブジェクトへのポインタを維持するための最良の方法です。
var myArray = [
{name: 'deepak', place: 'bangalore'},
{name: 'chirag', place: 'bangalore'},
{name: 'alok', place: 'berhampur'},
{name: 'chandan', place: 'mumbai'}`enter code here`
];
var toRemove = [
{name: 'deepak', place: 'bangalore'},
{name: 'alok', place: 'berhampur'}
];`enter code here`
myArray = myArray.filter(ar => !toRemove.find(rm => (rm.name === ar.name && ar.place === rm.place) ))
組み込みのメソッドを使用せずにロジックを構築しています。最適化や変更を教えてください。私はそれがうまく働いているJSエディタでテストしました。
var myArray = [
{name: 'deepak', place: 'bangalore'},
{name: 'alok', place: 'berhampur'},
{name: 'chirag', place: 'bangalore'},
{name: 'chandan', place: 'mumbai'},
];
var toRemove = [
{name: 'chirag', place: 'bangalore'},
{name: 'deepak', place: 'bangalore'},
/*{name: 'chandan', place: 'mumbai'},*/
/*{name: 'alok', place: 'berhampur'},*/
];
var tempArr = [];
for( var i=0 ; i < myArray.length; i++){
for( var j=0; j<toRemove.length; j++){
var toRemoveObj = toRemove[j];
if(myArray[i] && (myArray[i].name === toRemove[j].name)) {
break;
}else if(myArray[i] && (myArray[i].name !== toRemove[j].name)){
var fnd = isExists(tempArr,myArray[i]);
if(!fnd){
var idx = getIdex(toRemove,myArray[i])
if (idx === -1){
tempArr.Push(myArray[i]);
}
}
}
}
}
function isExists(source,item){
var isFound = false;
for( var i=0 ; i < source.length; i++){
var obj = source[i];
if(item && obj && obj.name === item.name){
isFound = true;
break;
}
}
return isFound;
}
function getIdex(toRemove,item){
var idex = -1;
for( var i=0 ; i < toRemove.length; i++){
var rObj =toRemove[i];
if(rObj && item && rObj.name === item.name){
idex=i;
break;
}
}
return idex;
}