Javascript 용 밑줄로 중복 개체 제거


124

이런 종류의 배열이 있습니다.

var foo = [ { "a" : "1" }, { "b" : "2" }, { "a" : "1" } ];

다음과 같이 필터링하고 싶습니다.

var bar = [ { "a" : "1" }, { "b" : "2" }];

_.uniq를 사용해 보았지만 { "a" : "1" }자신과 같지 않기 때문에 작동하지 않는 것 같습니다. 재정의 된 같음 함수와 함께 밑줄 uniq를 제공하는 방법이 있습니까?


코드도 게시하십시오
Chetter Hummin 2012

같은 것이 { "a" : "2" }존재합니까? 그렇다면 그것을 고유하게 만드는 속성 또는 값입니까?
Matt

내가 키와 같은 속성을 가지고 할 네, 인덱스 사람이 다른 주제에 나에게 보여 주었다 구현, 그러나 나는 몇 가지 일반적인 라이브러리를 사용하여 내 코드를 청소 원
플러스 -

1
쾌락 변경 수락 답변.
Vadorequest 2014

답변:


232

.uniq / .unique는 콜백을받습니다.

var list = [{a:1,b:5},{a:1,c:5},{a:2},{a:3},{a:4},{a:3},{a:2}];

var uniqueList = _.uniq(list, function(item, key, a) { 
    return item.a;
});

// uniqueList = [Object {a=1, b=5}, Object {a=2}, Object {a=3}, Object {a=4}]

노트:

  1. 비교에 사용되는 콜백 반환 값
  2. 고유 한 반환 값이 사용 된 첫 번째 비교 개체
  3. underscorejs.org 는 콜백 사용이 없음을 보여줍니다.
  4. lodash.com 은 사용법을 보여줍니다

또 다른 예 : 콜백을 사용하여 목록에서 자동차 제조업체, 색상 추출


false에 필요하지 않습니다 _.uniq(). 또한 lodash 에서는 객체 _.uniq(a, 'a');의 속성 a을 뽑아 낼 것이기 때문에 이와 같이 작성할 수 있습니다 .
Larry Battle

" '_.pluck'콜백 속기"는 isSorted에 대한 값을 전달하는 경우에만 작동합니다 (예 : _.uniq(a, false, 'a')github / bestiejs / lodash를 핑하고 문제가 가장자리에서 수정되었다고 말함). 따라서 기능을 사용하지 않는 경우 최신 버전인지 확인하십시오. 밑줄에는 문제가되지 않을 수 있습니다.
Shanimal 2013 년

2
반복자는 좋은 이름처럼 소리가 나지 않는다, 각 개체의 정체성을 결정하는 것입니다 기능과 같은 해시이다
후안 멘데스

lodash 문서와 더 일관되도록 콜백을 사용하도록 편집되었습니다. :)
Shanimal

1
jsbin의 예 는 업데이트를 가질 수 있습니다. (1) 제조사 : _ (cars) .uniq ( 'make'). map ( 'make'). valueOf () AND (2) 색상 : _ (cars) .uniq ( 'color'). map ( 'color' ) .valueOf (). 색상을 익히고 마감 할 수 있습니다. (모든 업그레이드하면 것을 드 lodash 사용)
비터 Tyburski

38

ID를 기반으로 중복을 제거하려는 경우 다음과 같이 할 수 있습니다.

var res = [
  {id: 1, content: 'heeey'},
  {id: 2, content: 'woah'}, 
  {id: 1, content:'foo'},
  {id: 1, content: 'heeey'},
];
var uniques = _.map(_.groupBy(res,function(doc){
  return doc.id;
}),function(grouped){
  return grouped[0];
});

//uniques
//[{id: 1, content: 'heeey'},{id: 2, content: 'woah'}]

허용되는 답변은 고유 식별자가 Date. 그러나 이것은 그렇습니다.
gunwin

17

Shiplu의 답변 구현.

var foo = [ { "a" : "1" }, { "b" : "2" }, { "a" : "1" } ];

var x = _.uniq( _.collect( foo, function( x ){
    return JSON.stringify( x );
}));

console.log( x ); // returns [ { "a" : "1" }, { "b" : "2" } ]

btw, 어떻게 4 개의 찬성표를 얻었나요? 결과의 속성을 얻으려면 각 배열 값을 객체로 되돌려 야합니다. 같은 뭔가 JSON.parse(x[0]).ax는이 문자열 배열의 객체의 배열이 아닌 때문이다. 또한 고유 값에 b 값을 추가하고 a / b 순서를 반전하면 더 이상 함수에서 고유 한 것으로 간주되지 않습니다. (예 :` "{\"a \ ": \"1 \ ", \"b \ ": 2}"! = "{\"b \ ": 2, \"a \ ": \"1 \ "} ") 뭔가 빠진 것 같지만 그 결과가 적어도 유용하지 않을까요? 여기에서 설명하는 jsbin입니다 jsbin.com/utoruz/2/edit을
Shanimal

1
당신은 동일한 키를 가지고 있지만 다른 순서로 구현이 중단되는 조건이 맞습니다. 하지만 키 a를 포함하지 않는 중복 개체가있을 수 있는데 왜 각 개체 의 키 를 확인하는지 잘 모르겠습니다 a. 그러나 a고유 ID 라면 이해가 될 것 입니다.
Larry Battle

제가 질문에 대답 할 때 질문의 초점이 재정의에있는 것 같았습니다 (a ==(=) b when a = b = {a:1}). 내 대답의 요점은 반복자였습니다. 동기를 신경 쓰지 않고 대답 해보려고했는데 뭐라도 될 수 있겠죠? (예를 들어 그들은 쇼의 자동차 목록에서 제조사, 색상 목록을 추출하고 싶을 수 있습니다. jsbin.com/evodub/2/edit ) 건배!
Shanimal

또한 질문하는 사람이 동기를 부여 할 때 간결한 답변을하는데 도움이된다고 생각합니다. 이것은 경주이기 때문에 나는 우선 순위를두고 필요한 경우 명확히하는 것을 선호합니다. 행복한 성 패트릭의 날.
Shanimal

이것은 중첩 배열 비교에 대한 내 질문에 답했기 때문에 다른 찬성표를주었습니다. 단지를 대체하는 방법을 찾고 있었다iterator
nevi_me

15

속성 ID가있을 때 이것이 내가 선호하는 밑줄 방식입니다.

var x = [{i:2}, {i:2, x:42}, {i:4}, {i:3}];
_.chain(x).indexBy("i").values().value();
// > [{i:2, x:42}, {i:4}, {i:3}]

12

밑줄 고유 lib를 사용하면 _id를 기반으로 목록을 고유하게 만든 다음 _id의 문자열 값을 반환합니다.

var uniqueEntities = _.uniq(entities, function (item, key, a) {
                                    return item._id.toString();
                                });

10

다음은 깊은 객체 비교를 사용하여 중복을 확인하는 간단한 솔루션입니다 (비효율적이고 해키 인 JSON으로 변환하지 않고).

var newArr = _.filter(oldArr, function (element, index) {
    // tests if the element has a duplicate in the rest of the array
    for(index += 1; index < oldArr.length; index += 1) {
        if (_.isEqual(element, oldArr[index])) {
            return false;
        }
    }
    return true;
});

배열에서 나중에 중복 된 요소가 있으면 모든 요소를 ​​필터링하여 마지막 중복 요소가 유지되도록합니다.

_.isEqual두 개체 간의 최적화 된 심층 비교를 수행하는 중복 사용에 대한 테스트는 자세한 내용은 밑줄 isEqual 문서 를 참조하세요.

편집 : _.filter더 깨끗한 접근 방식 을 사용하도록 업데이트되었습니다.


미리 정의 된 고유 속성에 의존하지 않습니까? 나는 그것을 좋아한다.
Don McCurdy 2014 년

1
작은 객체 배열에 적합한 솔루션이지만 루프 내의 루프는 고유 ID를 제공하는 것에 비해 비용이 많이 듭니다.
penner


7

반복자 기능 시도

예를 들어 첫 번째 요소를 반환 할 수 있습니다.

x = [['a',1],['b',2],['a',1]]

_.uniq(x,false,function(i){  

   return i[0]   //'a','b'

})

=> [[ 'a', 1], [ 'b', 2]]


초 인수는 또한 할 수있다, 실제로는 선택 사항입니다_.uniq(x,function(i){ return i[0]; });
jakecraige

3

여기 내 솔루션 (coffeescript)이 있습니다.

_.mixin
  deepUniq: (coll) ->
    result = []
    remove_first_el_duplicates = (coll2) ->

      rest = _.rest(coll2)
      first = _.first(coll2)
      result.push first
      equalsFirst = (el) -> _.isEqual(el,first)

      newColl = _.reject rest, equalsFirst

      unless _.isEmpty newColl
        remove_first_el_duplicates newColl

    remove_first_el_duplicates(coll)
    result

예:

_.deepUniq([ {a:1,b:12}, [ 2, 1, 2, 1 ], [ 1, 2, 1, 2 ],[ 2, 1, 2, 1 ], {a:1,b:12} ]) 
//=> [ { a: 1, b: 12 }, [ 2, 1, 2, 1 ], [ 1, 2, 1, 2 ] ]

3

밑줄 내가 사용했다 문자열을 ()iteratee의 기능

function isUniq(item) {
    return String(item.user);
}
var myUniqArray = _.uniq(myArray, isUniq);

0

저는이 간단한 해결책을 간단한 방법으로 풀고 싶었고 약간의 계산 비용이 들었습니다 ...하지만 최소한의 변수 정의를 가진 사소한 해결책이 아닌가요?

function uniq(ArrayObjects){
  var out = []
  ArrayObjects.map(obj => {
    if(_.every(out, outobj => !_.isEqual(obj, outobj))) out.push(obj)
  })
  return out
}

0
var foo = [ { "a" : "1" }, { "b" : "2" }, { "a" : "1" } ];
var bar = _.map(_.groupBy(foo, function (f) { 
        return JSON.stringify(f); 
    }), function (gr) { 
        return gr[0]; 
    }
);

이것을 분해 해보자. 먼저 문자열 값으로 배열 항목을 그룹화합니다.

var grouped = _.groupBy(foo, function (f) { 
    return JSON.stringify(f); 
});

grouped 다음과 같이 보입니다.

{
    '{ "a" : "1" }' = [ { "a" : "1" } { "a" : "1" } ],
    '{ "b" : "2" }' = [ { "b" : "2" } ]
}

그런 다음 각 그룹에서 첫 번째 요소를 가져옵니다.

var bar = _.map(grouped, function(gr)
    return gr[0]; 
});

bar 다음과 같이 보입니다. [ { "a" : "1" }, { "b" : "2" } ]

모두 합치면 :

var foo = [ { "a" : "1" }, { "b" : "2" }, { "a" : "1" } ];
var bar = _.map(_.groupBy(foo, function (f) { 
        return JSON.stringify(f); 
    }), function (gr) { 
        return gr[0]; 
    }
);

3
stackoverflow에 오신 것을 환영합니다. 제공 한 코드 외에도 문제가 해결되는 이유와 방법에 대한 설명을 제공하십시오.
jtate

좋은 전화. 감사. 작동 방식에 대한 분석으로 업데이트되었습니다.
Kelly Bigley

-5

속기에서 다음과 같이 할 수 있습니다.

_.uniq(foo, 'a')


솔루션은 객체의 배열을 위해 일하지만, 단지 배열하지 않습니다
Toucouleur
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.