객체 속성을 기준으로 배열 요소 제거


270

다음과 같은 객체 배열이 있습니다.

var myArray = [
    {field: 'id', operator: 'eq', value: id}, 
    {field: 'cStatus', operator: 'eq', value: cStatus}, 
    {field: 'money', operator: 'eq', value: money}
];

속성을 기준으로 특정 항목을 제거하려면 어떻게합니까?

예를 들어 'money'를 필드 속성으로 사용하여 배열 객체를 어떻게 제거합니까?

답변:


382

하나의 가능성 :

myArray = myArray.filter(function( obj ) {
    return obj.field !== 'money';
});

filter새로운 배열 이 생성됩니다. 원래 변수 myArray를 새 참조로 업데이트하더라도 원래 배열을 참조하는 다른 변수는 필터링 된 데이터를 가져 오지 않습니다 . 주의해서 사용하십시오.


6
참고 filter()인터넷 익스플로러 9 이상에서만 사용할 수 있습니다
jessegavin

@jessegavin 실제로. 기능을 모방 한 훌륭한 es5 shim 라이브러리 가 많이 있음을 언급 했어야 합니다 (레거시 브라우저를 지원하려는 경우)
jAndy

3
filter()새 배열을 만듭니다. 변수를 다시 할당하고 참조 할 수있는 다른 코드 영역이 없다는 것을 알면 좋습니다. 원래 배열 객체를 특별히 수정해야하는 경우에는 작동하지 않습니다.
Brian Glick

2
배열이 트리 구조 인 경우 ar beforeDeleteOperationArray = [{ "id": 3.1, "name": "test 3.1", "activityDetails": [{ "id": 22, "name": "test 3.1"}, { "ID": 23, "이름": "변경된 시험 23"}]}] 내가 삭제 ID하려는 : 23
forgottofly

@forgottofly good point-답변은 제한된 경우에만 작동합니다. 질문에 대한 답변을 찾았습니까?
JackTheKnife

88

배열을 반복 splice하고 원하지 않는 배열을 반복하십시오 . 사용하기 쉽도록 뒤로 반복하여 배열의 실제 특성을 고려하지 않아도됩니다.

for (var i = myArray.length - 1; i >= 0; --i) {
    if (myArray[i].field == "money") {
        myArray.splice(i,1);
    }
}

3
배열의 실제 특성은 무엇을 의미합니까? @Neit 다크 Absol
sisimh

29
@sisimh 그는 반복 논리의 일부로 길이를 사용하여 배열을 순회하고 요소가 제거되거나 추가되어 길이가 변경되면 배열의 끝에서 실행되거나 작업을 수행하지 않을 수 있음을 의미합니다 배열의 모든 항목. 뒤로 이동하면 이동 길이가 아닌 정적 0 인덱스를 향해 작동하므로 훨씬 덜 가능성이 있습니다.
Klors

2
배열이 트리 구조 인 경우 ar beforeDeleteOperationArray = [{ "id": 3.1, "name": "test 3.1", "activityDetails": [{ "id": 22, "name": "test 3.1"}, { "ID": 23, "이름": "변경된 시험 23"}]}] 내가 삭제 ID하려는 : 23
forgottofly

분명히 하나의 고유 한 요소 만 제거하려는 경우 성능에 대한 'if'문을 중단하여 루프가 나머지 배열을 불필요하게 반복하지 않도록 할 수 있습니다.
Patrick Borkowicz

@Klors 설명해 주셔서 감사합니다. 답변에서와 같이 항상 배열을 뒤로 읽는 것이 좋습니까?
kittu

37

field 속성으로 두 번째 객체를 제거한다고 가정 해보십시오.

ES6을 사용하면 이처럼 쉽습니다.

myArray.splice(myArray.findIndex(item => item.field === "cStatus"), 1)

6
나는 이것을 시도했지만 OP의 배열에서 세 번째 항목을 "제거"하는 대신 코드를 "필터링"하고 세 번째 항목 만 표시했습니다.
컴팩 LE2202x

1
2 년 후 @ CompaqLE2202x는 아마도 당신에게 이미 명백 할 것입니다. 그러나 미래 개발자들에게는 : splice원래 배열을 변경하므로, 반환되는 값은 제거 된 항목이지만 다음에 보면 myArray항목을 찾을 수 없습니다.
David Mulder

16

lodash의 findIndex 를 사용 하여 특정 요소의 색인을 가져온 다음이를 사용하여 결합 할 수 있습니다.

myArray.splice(_.findIndex(myArray, function(item) {
    return item.value === 'money';
}), 1);

최신 정보

ES6의 findIndex ()를 사용할 수도 있습니다

findIndex () 메소드는 제공된 테스트 함수를 만족하는 배열의 첫 번째 요소 색인을 리턴합니다. 그렇지 않으면 -1이 반환됩니다.

myArray.splice(myArray.findIndex(myArray, function(item) {
    return item.value === 'money';
}), 1);

배열은 트리 구조 란 무엇입니까?
forgottofly

@forgottofly 트리 구조? myArray여기에 객체 배열이 있다고 생각 합니다.
Sridhar

3
배열이 트리 구조 인 경우 var beforeDeleteOperationArray = [{ "id": 3.1, "name": "test 3.1", "activityDetails": [{ "id": 22, "name": "test 3.1"}, { "id": 23, "name": "변경된 테스트 23"}]}] id : 23을 삭제하고 싶습니다
잊어 버렸습니다

9

jQuery grep을 사용하는 또 다른 옵션이 있습니다. 전달 true함수와 일치 GREP 제거합니다 항목을 보장하기 위해 세 번째 매개 변수로.

users = $.grep(users, function(el, idx) {return el.field == "money"}, true)

이미 jQuery를 사용하고 있다면 shim이 필요하지 않으므로을 사용하는 대신 유용 할 수 있습니다 Array.filter.


7

ES6에서는 한 줄만 있습니다.

const arr = arr.filter(item => item.key !== "some value");

:)


3

다음은 jQuery를 사용하지 않는 경우의 코드입니다. 데모

var myArray = [
    {field: 'id', operator: 'eq', value: 'id'}, 
    {field: 'cStatus', operator: 'eq', value: 'cStatus'}, 
    {field: 'money', operator: 'eq', value: 'money'}
];

alert(myArray.length);

for(var i=0 ; i<myArray.length; i++)
{
    if(myArray[i].value=='money')
        myArray.splice(i);
}

alert(myArray.length);

많은 기능을 가진 밑줄 라이브러리를 사용할 수도 있습니다.

Underscore 는 많은 기능적 프로그래밍 지원을 제공하는 JavaScript 용 유틸리티 벨트 라이브러리입니다.


5
이것은 웹에 남겨 두는 매우 위험한 예입니다 ... 예제 데이터는 작동하지만 다른 것은 작동하지 않습니다. splice (i)는 값이 돈인 첫 번째 인스턴스에서 시작하여 이후에 배열의 모든 요소를 ​​제거하여 op의 요구 사항을 전혀 충족시키지 않음을 의미합니다. splice (i, 1)로 변경 한 경우 다음 순차 항목을 평가하지 않기 때문에 여전히 올바르지 않습니다 (i도 감소시켜야 함). 따라서 배열에서 제거 조작을 뒤로 처리하여 항목은 처리 할 다음 항목의 색인을 변경하지 않습니다.
Chris Schaller

3
var myArray = [
    {field: 'id', operator: 'eq', value: id}, 
    {field: 'cStatus', operator: 'eq', value: cStatus}, 
    {field: 'money', operator: 'eq', value: money}
];
console.log(myArray.length); //3
myArray = $.grep(myArray, function(element, index){return element.field == "money"}, true);
console.log(myArray.length); //2

요소는 배열의 객체입니다. 세 번째 매개 변수 true는 함수 논리에 실패한 요소 배열을 반환하고, 함수 논리에 false실패한 요소 배열을 반환합니다.


3

은 Using lodash 라이브러리 :

var myArray = [
    {field: 'id', operator: 'eq', value: 'id'}, 
    {field: 'cStatus', operator: 'eq', value: 'cStatus'}, 
    {field: 'money', operator: 'eq', value: 'money'}
];
var newArray = _.remove(myArray, function(n) {
  return n.value === 'money';;
});
console.log('Array');
console.log(myArray);
console.log('New Array');
console.log(newArray);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.js"></script>


2

위의 일부 주석을 기반으로 키 이름과 키 값을 기반으로 객체를 제거하는 방법은 코드입니다

 var items = [ 
  { "id": 3.1, "name": "test 3.1"}, 
  { "id": 22, "name": "test 3.1" }, 
  { "id": 23, "name": "changed test 23" } 
  ]

    function removeByKey(array, params){
      array.some(function(item, index) {
        return (array[index][params.key] === params.value) ? !!(array.splice(index, 1)) : false;
      });
      return array;
    }

    var removed = removeByKey(items, {
      key: 'id',
      value: 23
    });

    console.log(removed);

1

jAndy의 솔루션이 가장 좋지만 필터를 사용할 수 없으면 다음과 같은 작업을 수행 할 수 있습니다.

var myArray = [
    {field: 'id', operator: 'eq', value: 'id'}, 
    {field: 'cStatus', operator: 'eq', value: 'cStatus'}, 
    {field: 'money', operator: 'eq', value: "money"}
];

myArray.remove_key = function(key){
    var i = 0, 
        keyval = null;
    for( ; i < this.length; i++){
        if(this[i].field == key){
            keyval = this.splice(i, 1);
            break;
        }
    }
    return keyval;
}

1
filter ()에 의존 할 수없는 이유는 무엇입니까?
imperium2335

2
JavaScript 1.6의 일부이기 때문에 IE8 이하 또는 이전 버전의 브라우저에서는 지원되지 않습니다.
Rob M.

-1

lodash 라이브러리를 사용하면 간단합니다.

_.remove(myArray , { field: 'money' });
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.