[javascript] 일반 객체를 ES6 맵으로 변환하는 방법은 무엇입니까?

어떤 이유로 MDN 문서 에서이 간단한 것을 찾을 수 없습니다 (아마도 그냥 놓치고있을 수도 있습니다).

나는 이것이 작동 할 것으로 예상했다.

const map = new Map({foo: 'bar'});

map.get('foo'); // 'bar'

…하지만 첫 번째 줄은 TypeError: (var)[Symbol.iterator] is not a function

일반 개체에서지도를 만들려면 어떻게해야합니까? 먼저 키-값 쌍의 배열로 변환해야합니까?



답변

예, Map생성자는 키-값 쌍의 배열을 사용합니다.

Object.entriesES2017 (19.1.2.5) 에서 사용할 수있는 새로운 Object 정적 메서드 입니다.

const map = new Map(Object.entries({foo: 'bar'}));

map.get('foo'); // 'bar'

현재 Firefox 46 이상 및 Edge 14 이상 및 최신 버전의 Chrome에서 구현됩니다.

이전 환경을 지원해야하고 트랜스 파일이 옵션이 아닌 경우 georg에서 권장하는 것과 같은 polyfill을 사용하세요.

Object.entries = typeof Object.entries === 'function' ? Object.entries : obj => Object.keys(obj).map(k => [k, obj[k]]);


답변

생성기 함수를 사용 하여 nils의 답변Object.entries 및 / 또는 bergi의 답변을 참조하십시오. . 하지만 Object.entries문제는 질문을 받았다 때 아직 사양에 없었다, 그것은 4 단계에 있었다 하더라도 다시 2016년 4월 (단지)에서에 polyfill 사용하기 때문에 안전합니다. ( 여기 에 더 많은 단계가 있습니다 .) 그리고 생성기 함수는 ES2015에있었습니다. OP는 특히 중개자를 피하도록 요청했으며 발전기가 그것을 완전히 피하지는 않지만 아래 또는 (약간)보다 더 나은 작업을 수행합니다.Object.enties .

FWIW, 사용 Object.entries:

  • [name, value]전달할 배열의 배열을 만듭니다.new Map
  • 그만큼 Map생성자는 반복자를 얻을 수있는 배열 함수를 호출; 배열은 배열 인터 레이터 객체를 생성하고 반환합니다.
  • 그만큼 Map반복자 객체가 엔트리합니다 (얻을 것을 생성자가 사용하는 [name, value]배열)과지도를 구축

생성기 사용 :

  • 제너레이터 함수를 호출 한 결과로 제너레이터 객체를 생성합니다.
  • Map생성자는 그것에서 반복자를 얻기 위해 그 발전기 객체에 함수를 호출; 생성기 객체는 자신을 반환 합니다.
  • Map생성자 (반복자로) 발전기 객체의 항목합니다 (얻기 위해 사용하는 [name, value]배열)과지도를 구축

따라서 : 하나 더 적은 중개자 (의 배열 Object.entries).

그러나 사용 Object.entries이 더 간단하고 해당 어레이를 만드는 것이 99.999 %의 시간에 문제가되지 않습니다. 그러니 둘 중 하나입니다. 그러나 둘 다 아래보다 낫습니다. 🙂


원래 답변 :

을 초기화하려면 Map배열 배열과 같이 키 / 값 쌍을 배열로 반환하는 반복기를 사용할 수 있습니다.

const map = new Map([
    ['foo', 'bar']
]);

객체에서지도로의 기본 변환은 없지만 다음을 사용하여 쉽게 수행 할 수 있습니다 Object.keys.

const map = new Map();
let obj = {foo: 'bar'};
Object.keys(obj).forEach(key => {
    map.set(key, obj[key]);
});

물론이를 처리 할 작업자 함수를 제공 할 수 있습니다.

function buildMap(obj) {
    let map = new Map();
    Object.keys(obj).forEach(key => {
        map.set(key, obj[key]);
    });
    return map;
}

그때

const map = buildMap({foo: 'bar'});

또는 여기에 더 l33t-looking (아직도 문제가 있습니까?) 버전이 있습니다.

function buildMap(obj) {
    return Object.keys(obj).reduce((map, key) => map.set(key, obj[key]), new Map());
}

(예, Map#set지도 참조를 반환합니다. 어떤이는 것입니다 주장 abusagereduce.)

또는 우리는 모호성에 대해 정말로 과장 할 수 있습니다 .

const buildMap = o => Object.keys(o).reduce((m, k) => m.set(k, o[k]), new Map());

아니, 절대 그렇게하지 않을거야. 🙂


답변

먼저 키-값 쌍의 배열로 변환해야합니까?

아니요, 키-값 쌍 배열의 반복자로 충분합니다. 다음을 사용하여 중간 배열 생성을 피할 수 있습니다.

function* entries(obj) {
    for (let key in obj)
        yield [key, obj[key]];
}

const map = new Map(entries({foo: 'bar'}));
map.get('foo'); // 'bar'


답변

Nils의 답변은 객체를 맵으로 변환 하는 방법 을 설명 합니다. 그러나 OP는이 정보가 MDN 문서에서 어디에 있는지 궁금해했습니다. 원래 질문을 받았을 때는 없었을 수도 있지만 이제는 객체를지도변환이라는 제목 아래 Object.entries () 의 MDN 페이지에 있습니다.

객체를지도로 변환

new Map()생성자의 반복자를 받아 들인다 entries. 로 Object.entries쉽게 변환 할 수 있습니다 ObjectMap:

const obj = { foo: 'bar', baz: 42 };
const map = new Map(Object.entries(obj));
console.log(map); // Map { foo: "bar", baz: 42 }

답변

const myMap = new Map(
    Object
        .keys(myObj)
        .map(
            key => [key, myObj[key]]
        )
)


답변

또는 lodash toPairs 메서드를 사용할 수 있습니다 .

const _ = require('lodash');
const map = new Map(_.toPairs({foo: 'bar'}));


답변

ES6

객체를지도로 변환 :

const objToMap = (o) => new Map(Object.entries(o));

지도를 객체로 변환 :

const mapToObj = (m) => [...m].reduce( (o,v)=>{ o[v[0]] = v[1]; return o; },{} )

참고 : mapToObj 함수는 맵 키가 문자열이라고 가정합니다 (그렇지 않으면 실패 함).