다음과 같은 객체 배열이 있다고 가정해 보겠습니다.
const arr = [
{id:123, value:"value1", name:"Name1"},
{id:124, value:"value2", name:"Name1"},
{id:125, value:"value3", name:"Name2"},
{id:126, value:"value4", name:"Name2"}
];배열 속 객체들을 살펴보면 일부 객체의 'name' 속성 값이 서로 중복되어 있는 것을 확인할 수 있습니다.
이번 글에서는 이러한 객체 배열을 입력으로 받아, 배열에 존재하는 'name' 속성 값들 중에서 중복을 제거하고 고유한 값만으로 구성된 새로운 문자열 배열을 반환하는 JavaScript 함수를 작성해 보겠습니다.
따라서 위 입력 데이터에 대한 기대 출력은 다음과 같습니다.
const output = ["Name1", "Name2"];
예제
이를 구현한 전체 코드는 아래와 같습니다.
const arr = [
{id:123, value:"value1", name:"Name1"},
{id:124, value:"value2", name:"Name1"},
{id:125, value:"value3", name:"Name2"},
{id:126, value:"value4", name:"Name2"}
];
const pickNames = (arr = []) => {
const res = [];
for (let i = arr.length; i--;) {
if (res.indexOf(arr[i].name) < 0) {
res.push(arr[i].name);
}
}
return res;
};
console.log(pickNames(arr));코드 동작 원리
- 배열의 끝부터 앞까지 역순으로 순회하며 각 객체의 'name' 값을 하나씩 확인합니다.
res.indexOf()를 사용해 해당 이름이 결과 배열에 이미 존재하는지 검사합니다.- 존재하지 않는 경우에만
push()로 추가하기 때문에 중복 값은 자연스럽게 걸러집니다.
출력
콘솔에 출력되는 결과는 다음과 같습니다.
[ 'Name2', 'Name1' ]
배열을 역순으로 순회했기 때문에 결과 배열에는 'Name2'가 먼저 담기게 됩니다. 순서가 중요하다면 Array.prototype.reverse() 또는 정방향 순회로 조정할 수 있습니다.
참고: Set을 활용한 더 간결한 방법
ES6 이상 환경이라면 map()과 Set을 조합해 한 줄로 처리할 수도 있습니다.
const pickNames = (arr = []) => [...new Set(arr.map(obj => obj.name))]; console.log(pickNames(arr)); // [ 'Name1', 'Name2' ]
Set은 자동으로 중복을 제거해 주므로 별도의 indexOf 검사 없이 깔끔하고 직관적인 코드를 작성할 수 있습니다. 실무에서는 가독성과 성능 면에서 이 방식을 권장합니다.