Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

JavaScript 객체에서 특정 값으로 키 찾는 방법

JavaScript로 개발하다 보면 배열을 값으로 가지는 객체에서 특정 값이 어느 키에 속하는지 찾아야 하는 경우가 종종 있습니다. 이 글에서는 그러한 문제를 해결하는 함수를 작성하는 방법을 살펴보겠습니다.

문제 상황

다음과 같이 각 키의 값으로 문자열 배열을 가지는 객체가 있다고 가정해 보겠습니다.

const obj = {
  'key1': ['value11', 'value12', 'value13', 'value14', 'value15'],
  'key2': ['value21', 'value22', 'value23', 'value24', 'value25',
  'value26', 'value27'],
  'key3': ['value31', 'value32', 'value33', 'value34'],
  'key4': ['value41', 'value42'],
};

우리가 작성해야 할 JavaScript 함수는 첫 번째 인수로 위와 같은 객체를, 두 번째 인수로 검색할 값 문자열을 받습니다. 그런 다음 입력된 값이 어떤 키의 배열에 속하는지 확인하고 해당 키를 반환해야 합니다.

'value13' → 'key1'
'value32' → 'key3'

예제 코드

이 문제를 해결하는 코드는 다음과 같습니다.

const obj = {
  'key1': ['value11', 'value12', 'value13', 'value14', 'value15'],
  'key2': ['value21', 'value22', 'value23', 'value24', 'value25',
  'value26', 'value27'],
  'key3': ['value31', 'value32', 'value33', 'value34'],
  'key4': ['value41', 'value42'],
};
const searchByValue = (obj, val) => {
  for (let key in obj) {
    if (obj[key].indexOf(val) !== -1) {
      return key;
    };
  };
  return null;
};
console.log(searchByValue(obj, 'value32'));

출력 결과

위 코드를 실행하면 콘솔에 다음과 같은 결과가 출력됩니다.

key3

코드 동작 원리

이 함수의 동작 방식은 다음과 같습니다.

for...in 루프를 사용해 객체의 모든 키를 하나씩 순회합니다. 각 키에 대해 indexOf() 메서드로 해당 키의 배열 안에 검색하려는 값이 존재하는지 확인합니다. indexOf()는 요소를 찾으면 그 인덱스를 반환하고, 찾지 못하면 -1을 반환하므로 반환값이 -1이 아니라면 값이 존재한다는 의미입니다. 값을 찾으면 즉시 해당 키를 반환하고, 모든 키를 순회한 후에도 값을 찾지 못하면 null을 반환합니다.

더 간결한 대안: find 메서드 활용

ES6 이상 환경이라면 Object.keys()와 배열의 find() 메서드를 조합해 더 간결하게 작성할 수도 있습니다.

const searchByValue = (obj, val) =>
  Object.keys(obj).find(key => obj[key].includes(val)) || null;

console.log(searchByValue(obj, 'value32')); // key3
console.log(searchByValue(obj, 'value99')); // null

find() 메서드는 조건을 만족하는 첫 번째 요소를 반환하므로, 값이 여러 키에 중복해서 존재하는 경우에도 가장 먼저 발견된 키를 반환합니다. 또한 includes()를 사용하면 indexOf() !== -1 비교보다 코드의 의도가 더 명확하게 드러납니다.

마무리

값이 아닌 키를 기준으로 데이터를 조회하는 것이 일반적이지만, 실무에서는 역방향 검색이 필요한 경우도 생각보다 많습니다. 데이터 구조 설계 단계에서 이런 검색이 자주 필요하다는 것을 안다면, 값과 키를 매핑해 두는 별도의 색인(index) 객체를 만들어 두는 것도 성능 면에서 좋은 선택이 될 수 있습니다.