[javascript] 객체의 속성 값으로 색인 된 객체 배열을 해시 맵으로 변환

사용 사례

유스 케이스는 해시 맵의 키로 사용하고 오브젝트 자체로 값을 평가하고 사용하기 위해 제공된 문자열 또는 함수를 기반으로 오브젝트 배열을 해시 맵으로 변환하는 것입니다. 이것을 사용하는 일반적인 경우는 객체 배열을 객체의 해시 맵으로 변환하는 것입니다.

암호

다음은 객체 배열을 객체의 속성 값으로 색인화 한 해시 맵으로 변환하는 JavaScript의 작은 스 니펫입니다. 해시 맵의 키를 동적으로 평가하는 기능을 제공 할 수 있습니다 (런타임). 이것이 미래의 누군가를 돕기를 바랍니다.

function isFunction(func) {
    return Object.prototype.toString.call(func) === '[object Function]';
}

/**
 * This function converts an array to hash map
 * @param {String | function} key describes the key to be evaluated in each object to use as key for hashmap
 * @returns Object
 * @Example 
 *      [{id:123, name:'naveen'}, {id:345, name:"kumar"}].toHashMap("id")
 *      Returns :- Object {123: Object, 345: Object}
 *
 *      [{id:123, name:'naveen'}, {id:345, name:"kumar"}].toHashMap(function(obj){return obj.id+1})
 *      Returns :- Object {124: Object, 346: Object}
 */
Array.prototype.toHashMap = function(key) {
    var _hashMap = {}, getKey = isFunction(key)?key: function(_obj){return _obj[key];};
    this.forEach(function (obj){
        _hashMap[getKey(obj)] = obj;
    });
    return _hashMap;
};

여기서 요점을 찾을 수 있습니다 . 객체 배열을 HashMap으로 변환 합니다.



답변

이것은 다음과 관련이 있습니다 Array.prototype.reduce.

var arr = [
    { key: 'foo', val: 'bar' },
    { key: 'hello', val: 'world' }
];

var result = arr.reduce(function(map, obj) {
    map[obj.key] = obj.val;
    return map;
}, {});

console.log(result);
// { foo:'bar', hello:'world' }

참고 : Array.prototype.reduce() IE9 +이므로 이전 브라우저를 지원 해야하는 경우 polyfill해야합니다.


답변

ES6 Map ( 꽤 잘 지원됨 )을 사용하여 다음을 시도 할 수 있습니다.

var arr = [
    { key: 'foo', val: 'bar' },
    { key: 'hello', val: 'world' }
];

var result = new Map(arr.map(i => [i.key, i.val]));

// When using TypeScript, need to specify type:
// var result = arr.map((i): [string, string] => [i.key, i.val])

// Unfortunately maps don't stringify well.  This is the contents in array form.
console.log("Result is: " + JSON.stringify([...result])); 
// Map {"foo" => "bar", "hello" => "world"}


답변

lodash , 이것은 사용하여 수행 할 수 있습니다 keyBy를 :

var arr = [
    { key: 'foo', val: 'bar' },
    { key: 'hello', val: 'world' }
];

var result = _.keyBy(arr, o => o.key);

console.log(result);
// Object {foo: Object, hello: Object}


답변

ES6 spread + Object.assign 사용 :

array = [{key: 'a', value: 'b', redundant: 'aaa'}, {key: 'x', value: 'y', redundant: 'zzz'}]

const hash = Object.assign({}, ...array.map(s => ({[s.key]: s.value})));

console.log(hash) // {a: b, x: y}


답변

스프레드 연산자 사용 :

const result = arr.reduce(
    (accumulator, target) => ({ ...accumulator, [target.key]: target.val }),
    {});

jsFiddle 의 코드 스 니펫 시연 .


답변

JavaScript Object 대신 Array.prototype.reduce () 및 실제 JavaScript Map을 사용할 수 있습니다 .

let keyValueObjArray = [
  { key: 'key1', val: 'val1' },
  { key: 'key2', val: 'val2' },
  { key: 'key3', val: 'val3' }
];

let keyValueMap = keyValueObjArray.reduce((mapAccumulator, obj) => {
  // either one of the following syntax works
  // mapAccumulator[obj.key] = obj.val;
  mapAccumulator.set(obj.key, obj.val);

  return mapAccumulator;
}, new Map());

console.log(keyValueMap);
console.log(keyValueMap.size);

지도와 객체의 차이점은 무엇입니까?
이전에는 Map이 JavaScript로 구현되기 전에 유사한 구조로 인해 Object가 Map으로 사용되었습니다.
사용 사례에 따라 키를 주문해야하거나지도 크기에 액세스해야하거나지도에서 자주 추가 및 제거해야하는 경우지도가 바람직합니다.

MDN 문서 에서 인용 :
객체는 키와 값을 설정하고, 값을 검색하고, 키를 삭제하고, 키에 무언가가 저장되어 있는지 여부를 감지 할 수 있다는 점에서 맵과 유사합니다. 이 때문에 (및 내장 대안이 없기 때문에) 객체는 역사적으로지도로 사용되었습니다. 그러나 어떤 경우에는 맵 사용을 선호하는 중요한 차이점이 있습니다.

  • 객체의 키는 문자열과 심볼이지만 함수, 객체 및 기본 요소를 포함하여지도의 모든 값이 될 수 있습니다.
  • 객체에 추가 된 키가 아닌 맵의 키가 정렬됩니다. 따라서 반복 할 때 Map 객체는 삽입 순서대로 키를 반환합니다.
  • size 속성을 사용하여 Map의 크기를 쉽게 얻을 수 있지만 Object의 속성 수는 수동으로 결정해야합니다.
  • 맵은 반복 가능하므로 직접 반복 할 수있는 반면, 오브젝트를 반복하려면 키를 가져 와서 반복해야합니다.
  • 객체에는 프로토 타입이 있으므로주의하지 않으면 키와 충돌 할 수있는 기본 키가 맵에 있습니다. ES5부터는 map = Object.create (null)을 사용하여 무시할 수 있지만 거의 수행되지 않습니다.
  • 키 쌍을 자주 추가 및 제거하는 시나리오에서 맵 성능이 향상 될 수 있습니다.

답변

새로운 Object.fromEntries()방법을 사용할 수 있습니다 .

예:

const array = [
   {key: 'a', value: 'b', redundant: 'aaa'},
   {key: 'x', value: 'y', redundant: 'zzz'}
]

const hash = Object.fromEntries(
   array.map(e => [e.key, e.value])
)

console.log(hash) // {a: b, x: y}