[javascript] JavaScript에서 객체 배열에서 중복 제거

객체 배열을 포함하는 객체가 있습니다.

things = new Object();

things.thing = new Array();

things.thing.push({place:"here",name:"stuff"});
things.thing.push({place:"there",name:"morestuff"});
things.thing.push({place:"there",name:"morestuff"});

배열에서 중복 객체를 제거하는 가장 좋은 방법이 무엇인지 궁금합니다. 예를 들어, things.thing은 …

{place:"here",name:"stuff"},
{place:"there",name:"morestuff"}



답변

기본 방법은 다음과 같습니다.

var obj = {};

for ( var i=0, len=things.thing.length; i < len; i++ )
    obj[things.thing[i]['place']] = things.thing[i];

things.thing = new Array();
for ( var key in obj )
    things.thing.push(obj[key]);


답변

어떻게 어떤 약 es6마법?

things.thing = things.thing.filter((thing, index, self) =>
  index === self.findIndex((t) => (
    t.place === thing.place && t.name === thing.name
  ))
)

참조 URL

보다 일반적인 해결책은 다음과 같습니다.

const uniqueArray = things.thing.filter((thing, index) => {
  const _thing = JSON.stringify(thing);
  return index === things.thing.findIndex(obj => {
    return JSON.stringify(obj) === _thing;
  });
});

Stackblitz 예


답변

밑줄 이나 lodash 와 같은 Javascript 라이브러리를 사용할 수 있으면 _.uniq해당 라이브러리 에서 함수를 살펴 보는 것이 좋습니다 . 보낸 사람 lodash:

_.uniq(array, [isSorted=false], [callback=_.identity], [thisArg])

기본적으로 여기에 객체 리터럴이있는 배열을 전달하고 원래 데이터 배열에서 중복을 제거하려는 속성을 다음과 같이 전달합니다.

var data = [{'name': 'Amir', 'surname': 'Rahnama'}, {'name': 'Amir', 'surname': 'Stevens'}];
var non_duplidated_data = _.uniq(data, 'name'); 

업데이트 : Lodash는 이제도 도입했습니다 .uniqBy.


답변

단일 필드의 중복을 기반으로 배열에서 중복 객체를 제거 해야하는 것과 동일한 요구 사항이 있습니다. 여기에서 코드를 찾았습니다 : Javascript : 객체 배열에서 중복 제거

따라서 내 예제에서는 licenseNum 문자열 값이 중복 된 배열에서 객체를 제거하고 있습니다.

var arrayWithDuplicates = [
    {"type":"LICENSE", "licenseNum": "12345", state:"NV"},
    {"type":"LICENSE", "licenseNum": "A7846", state:"CA"},
    {"type":"LICENSE", "licenseNum": "12345", state:"OR"},
    {"type":"LICENSE", "licenseNum": "10849", state:"CA"},
    {"type":"LICENSE", "licenseNum": "B7037", state:"WA"},
    {"type":"LICENSE", "licenseNum": "12345", state:"NM"}
];

function removeDuplicates(originalArray, prop) {
     var newArray = [];
     var lookupObject  = {};

     for(var i in originalArray) {
        lookupObject[originalArray[i][prop]] = originalArray[i];
     }

     for(i in lookupObject) {
         newArray.push(lookupObject[i]);
     }
      return newArray;
 }

var uniqueArray = removeDuplicates(arrayWithDuplicates, "licenseNum");
console.log("uniqueArray is: " + JSON.stringify(uniqueArray));

결과 :

uniqueArray는 다음과 같습니다.

[{"type":"LICENSE","licenseNum":"10849","state":"CA"},
{"type":"LICENSE","licenseNum":"12345","state":"NM"},
{"type":"LICENSE","licenseNum":"A7846","state":"CA"},
{"type":"LICENSE","licenseNum":"B7037","state":"WA"}]


답변

ES6 + 용 최단 라이너

id배열에서 고유 한를 찾으십시오 .

arr.filter((v,i,a)=>a.findIndex(t=>(t.id === v.id))===i)

여러 속성 ( placename)으로 고유

arr.filter((v,i,a)=>a.findIndex(t=>(t.place === v.place && t.name===v.name))===i)

모든 속성에 고유함 (대형 배열의 경우 속도가 느림)

arr.filter((v,i,a)=>a.findIndex(t=>(JSON.stringify(t) === JSON.stringify(v)))===i)

마지막 발생을 유지하십시오.

arr.slice().reverse().filter((v,i,a)=>a.findIndex(t=>(t.id === v.id))===i).reverse()


답변

Set을 사용하는 하나의 라이너

var things = new Object();

things.thing = new Array();

things.thing.push({place:"here",name:"stuff"});
things.thing.push({place:"there",name:"morestuff"});
things.thing.push({place:"there",name:"morestuff"});

// assign things.thing to myData for brevity
var myData = things.thing;

things.thing = Array.from(new Set(myData.map(JSON.stringify))).map(JSON.parse);

console.log(things.thing)

설명:

  1. new Set(myData.map(JSON.stringify))세트를 만듭니다문자열 화 된 myData 요소를 사용하여 객체를 .
  2. 객체 설정은 모든 요소가 고유한지 확인합니다.
  3. 그런 다음 Array.from을 사용하여 생성 된 집합의 요소를 기반으로 배열을 만듭니다.
  4. 마지막으로 JSON.parse를 사용하여 문자열 화 된 요소를 다시 개체로 변환합니다.

답변

한 줄에 ES6 + 를 사용하면 키를 사용 하여 고유 한 객체 목록을 얻을 수 있습니다.

const unique = [...new Map(arr.map(item => [item[key], item])).values()]

함수에 넣을 수 있습니다.

function getUniqueListBy(arr, key) {
    return [...new Map(arr.map(item => [item[key], item])).values()]
}

다음은 실제 예입니다.

const arr = [
    {place: "here",  name: "x", other: "other stuff1" },
    {place: "there", name: "x", other: "other stuff2" },
    {place: "here",  name: "y", other: "other stuff4" },
    {place: "here",  name: "z", other: "other stuff5" }
]

function getUniqueListBy(arr, key) {
    return [...new Map(arr.map(item => [item[key], item])).values()]
}

const arr1 = getUniqueListBy(arr, 'place')

console.log("Unique by place")
console.log(JSON.stringify(arr1))

console.log("\nUnique by name")
const arr2 = getUniqueListBy(arr, 'name')

console.log(JSON.stringify(arr2))

작동 원리

먼저 배열을 지도 의 입력으로 사용할 수있는 방식으로 다시 매핑 합니다.

arr.map (항목 => [항목 [키], 항목]);

즉, 배열의 각 항목이 2 개의 요소가있는 다른 배열로 변환됩니다. 선택한 키 첫번째 요소로서 전체 초기 항목 번째 요소로서,이 항목 (예.이라고 배열 엔트리 , 맵 엔트리 ). 그리고 여기 공식 문서가 있습니다 지도 생성자에 배열 항목을 추가하는 방법을 보여주는 예제와 함께.

키가 배치 된 예 :

[["here", {place: "here",  name: "x", other: "other stuff1" }], ...]

두 번째로,이 수정 된 배열을 Map 생성자에 전달하면 마술이 일어납니다. Map은 중복 키 값을 제거하고 동일한 키의 마지막 삽입 값만 유지합니다.
참고 : Map은 삽입 순서를 유지합니다. ( 지도와 객체의 차이점 확인 )

새 맵 (위에 방금 매핑 한 항목 배열)

셋째, 맵 값을 사용하여 원래 항목을 검색하지만 이번에는 중복되지 않습니다.

새 맵 (mappedArr) .values ​​()

마지막으로,이 값을 새로운 배열에 추가하여 초기 구조로보고 다음을 반환합니다.

[… 새 맵 (mappedArr) .values ​​()] 반환