[javascript] 다른 배열에 포함 된 모든 요소 제거

다른 배열에있는 경우 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()and를 사용 하고 inArray()있습니다.

myArray = $.grep(myArray, function(value) {
    return $.inArray(value, toRemove) < 0;
});

루핑 및 스플 라이스 없이이 작업을 수행하는 순수한 자바 스크립트 방법이 있습니까?



답변

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 세트 는 두 배열의 다른 요소를 계산하는 데 사용할 수 있습니다.

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

답변

새로운 ES5를 사용할 수 없다면 filter두 개의 루프가 붙어 있다고 생각합니다.

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