[javascript] 배열에서 중복 제거

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

var array = [
    {id:123, value:"value1", name:"Name1"},
    {id:124, value:"value2", name:"Name1"},
    {id:125, value:"value3", name:"Name2"},
    {id:126, value:"value4", name:"Name2"}
    ...
];

보시다시피 일부 이름은 반복됩니다. 이름 만있는 새 배열을 얻고 싶지만 일부 이름이 반복되면 다시 추가하고 싶지 않습니다. 이 배열을 원합니다.

var newArray = ["Name1", "Name2"];

나는 이것을 시도하고있다 map:

var newArray = array.map((a) => {
    return a.name;
});

그러나 문제는 이것이 반환된다는 것입니다.

newArray = ["Name1", "Name1", "Name2", "Name2"];

내부 map에 조건을 설정 하여 이미 존재하는 요소를 반환하지 않도록하려면 어떻게해야합니까? 이 작업을 map다른 ECMAScript 5 또는 ECMAScript 6 기능 으로 수행하고 싶습니다 .



답변

ES6를 사용 Set하면 개체의 이름 만 매핑 한 후 고유 한 값을 사용할 수 있습니다 .

이 제안은 새 배열에서 항목을 수집하기 위해 스프레드 구문... 을 사용합니다 .

const array = [{ id: 123, value: "value1", name:"Name1" }, { id: 124, value: "value2", name: "Name1" }, { id: 125, value: "value3", name: "Name2" }, { id: 126, value: "value4", name: "Name2" }],
      names = [...new Set(array.map(a => a.name))];

console.log(names);


답변

ES 6 (Set 없음)이 아닌 JavaScript 솔루션을 찾고 있다면 Array의 reduce방법을 사용할 수 있습니다 .

var array=[
  {id:123, value:"value1", name:"Name1"},
  {id:124, value:"value2", name:"Name1"},
  {id:125, value:"value3", name:"Name2"},
  {id:126, value:"value4", name:"Name2"}
];
var names = array.reduce(function (a, b) {
  if (a.indexOf(b.name) == -1) {
    a.push(b.name)
  }
  return a;
}, []);

console.log(names);


답변

개인적으로 모든 사람들이 ES 6을 좋아하는 이유를 모르겠습니다. 이것이 제 코드라면 가능한 한 많은 브라우저를 지원하고 싶습니다.

var array=[
{id:123, value:"value1", name:"Name1"},
{id:124, value:"value2", name:"Name1"},
{id:125, value:"value3", name:"Name2"},
{id:126, value:"value4", name:"Name2"}
];

   // Create array of unique names
var a = (function(a){
  for (var i = array.length; i--;)
    if (a.indexOf(array[i].name) < 0) a.push(array[i].name);
  return a;
})([]);

console.log(a);


답변

또한 단순히 결합 수 mapfilter

var array = [
  {id:123, value:"value1", name:"Name1"},
  {id:124, value:"value2", name:"Name1"},
  {id:125, value:"value3", name:"Name2"},
  {id:126, value:"value4", name:"Name2"}
];

var unique = array
  .map( item => item.name )
  .filter( ( item, idx, arr ) => arr.indexOf( item ) == idx ) 

console.log(unique)


답변

Object.keys () 를 사용 하여 키가 파괴 된 이름 인 Array.prototype.reduce () 를 사용하여 반복 array변수 의 객체 결과에서 주어진 객체의 고유 한 열거 가능한 속성 이름의 배열을 가져올 수 있습니다.

암호:

const array = [{id:123, value:"value1", name:"Name1"}, {id:124, value:"value2", name:"Name1"}, {id:125, value:"value3", name:"Name2"}, {id:126, value:"value4", name:"Name2"}],
      names = Object.keys(array.reduce((a, { name }) => (a[name] = 1, a), {}))

console.log(names)


답변

여기에 많은 좋은 답변이 있습니다. 저는 여러분에게 또 다른 관점을주기를 희망하면서 다양성을 가지고 기여하고 싶습니다.

배열은 JavaScript에서 객체 유형이므로 동시에 해시로 사용할 수 있습니다. 이 기능을 사용하면 O (n) 시간 복잡성으로 단일 감소 작업으로 수행 할 작업을 크게 단순화 할 수 있습니다.

배열 키 이외의 일부 속성을 보유하는 배열이 마음에 들지 않으면 별도의 해시 객체를 유지하는 것도 고려할 수 있습니다.

var array = [{id:123, value:"value1", name:"Name1"},
             {id:124, value:"value2", name:"Name1"},
             {id:125, value:"value3", name:"Name2"},
             {id:126, value:"value4", name:"Name2"}
            ],
result = array.reduce((p,c) => p[c.name] ? p : (p[c.name] = true, p.push(c.name), p), []);
console.log(result);


답변

name값만 필요하다면 a Set가 갈 길이 라는 데 동의합니다 .

그러나name 속성을 기반으로 고유 한 개체의 배열을 얻으려면 Map. 맵을 만드는 빠른 방법은 [key, value]배열 배열을 사용하는 것입니다.

const array = [{ id: 123, value: "value1", name:"Name1" }, { id: 124, value: "value2", name: "Name1" }, { id: 125, value: "value3", name: "Name2" }, { id: 126, value: "value4", name: "Name2" }],
      unique = new Map(array.map(obj => [obj.name, obj]));

// To get the unique objects
const uniques = Array.from(unique.values());

// Get the names like you already did:
console.log("Names:", uniques.map(obj => obj.name));

// If you ever need the complete array of unique objects, you got a ref:
console.log(JSON.stringify(uniques));
.as-console-wrapper { min-height: 100%; }

의 추가 이점은 소스 개체와의 연결을 끊지 않고 고유하지 않은 항목을 잘라내 Map는 두 filter기능을 모두 얻을 수 있다는 것 입니다. 물론 고유 한 개체 집합을 여러 번 참조해야하는 경우에만 필요합니다.