본문 바로가기

Lang

[js]배열에서 중복된 값 처리하는 몇 가지 예.

js 배열 안에 중복된 값이 있나 체크하는 깔끔한 방법.

function hasDuplicates(array) {
   return (new Set(array)).size !== array.length;
}


배열 안에 중복된 값들이 있을 때 (1)unique 한 값만 추출 (2) 값들이 몇 번 씩 들어 있는지 카운트 (3)값들의 index 를 구하는 방법을 온라인에 있는 filter, reduce 함수 예를 이용해서 구현해본 거.

var fruits = ["banana", "orange", "grape", "orange", "grape", "grape", "apple"];

var onlyUnique = function (value, index, self) { 
    return self.indexOf(value) === index;
}

var dupIndexer = function(accumulator, val, index, array) {
  if (accumulator.hasOwnProperty(val)) {
    accumulator[val].push(index);
  } else {
    accumulator[val] = [index];
  }
  return accumulator;
}

var dupCounter = function(accumulator, val, index, array) {
  if (accumulator.hasOwnProperty(val)) {
    accumulator[val] = accumulator[val] + 1;
  } else {
    accumulator[val] = 1;
  }
  return accumulator;
}

var unique = fruits.filter( onlyUnique );  // (1)
console.log("Unique : " + unique);

var dupCount = fruits.reduce(dupCounter, {});  // (2)
console.log(dupCount);

var dupIndex = fruits.reduce(dupIndexer, {});  // (3)
console.log(dupIndex);

중복된 값의 nth 인덱스를 찾는 함수 구현해본 거. indexOf 나 lastIndexOf 처럼 쓸 수 있게 prototype 을 살짝 이용해서 ...

Array.prototype.nthIndexOf = function(key, nth) {
   var dupIndex = this.reduce(dupIndexer, {});
   return dupIndex[key].length >= nth?dupIndex[key][nth - 1]:-1;
}

console.log(fruits.nthIndexOf("orange", 2));
console.log(fruits.nthIndexOf("orange", 3));
console.log(fruits.indexOf("grape"))
console.log(fruits.nthIndexOf("grape", 1));
console.log(fruits.lastIndexOf("grape"))
console.log(fruits.nthIndexOf("grape", 3));

앞의 dupIndexer 는 배열에서 각 값의 인덱스를 모두 구하는거고 스택오버에서 찾은 이번거는 특정 값의 모든 인덱스를 배열로 리턴해주는 함수.

function getAllIndexes(arr, val) {
    var indexes = [], i;
    for(i = 0; i < arr.length; i++) {
        if(arr[i] === val) {
            indexes.push(i);
        }
    }
    return indexes;
}

앞 getAllIndexes 의 filter 버전입니다. filter 함수 자체는 인덱스가 아닌 값의 배열을 반환하는데 이 샘플은 map과 filter 그리고 isFinite 함수를 결합해서 그 문제를 해결했네요(어디서 찾은건지는 잊어먹었어요)

function getAllIndexes1(name) {
    return fruits.map(function(obj, index) {
        if(obj == name) {
            return index;
        }
    }).filter(isFinite);
}
console.log(getAllIndexes1("grape"))