По какой-то причине я не могу найти эту простую вещь в документах MDN (может быть, мне ее просто не хватает).
Я ожидал, что это сработает:
const map = new Map({foo: 'bar'});
map.get('foo'); // 'bar'
... но первая строка бросает TypeError: (var)[Symbol.iterator] is not a function
Как создать карту из простого объекта? Мне действительно нужно сначала преобразовать его в массив массивов пар ключ-значение?
javascript
ecmascript-6
Каллум
источник
источник
Object.entries
действительно лучший подходObject.keys
, и подход функции генератора Берги немного более прямой, чем любойObject.keys
илиObject.entries
.Ответы:
Да,
Map
конструктор принимает массив пар ключ-значение.Object.entries
- новый статический метод Object, доступный в ES2017 (19.1.2.5) .В настоящее время он реализован в Firefox 46+ и Edge 14+ и более новых версиях Chrome.
Если вам нужна поддержка более старых сред, а транспиляция вам не подходит, используйте полифил, такой как рекомендованный georg:
источник
Object.entries = obj => Object.keys(obj).map(k => [k, obj[k]])
Object.entries
приземлился в Node 7.x собственно (без флага), кстатиСм. Ответ nils с использованием
Object.entries
и / или ответ Bergi с использованием функции генератора . ХотяObject.entries
когда задавался вопрос, он еще не входил в спецификацию, но он находился на этапе 4 , поэтому его можно было полифиллировать и использовать даже в апреле 2016 года (просто). (Подробнее об этапах здесь .) И функции генератора были в 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% случаев. Так что действительно, любой. Но они оба лучше, чем ниже. :-)Оригинальный ответ:
Для инициализации a
Map
вы можете использовать любой итератор, который возвращает пары ключ / значение в виде массивов, например массив массивов:Встроенного преобразования из объекта в карту нет, но это легко сделать с помощью
Object.keys
:Вы, конечно, можете дать себе рабочую функцию для этого:
затем
Или вот более l33t-выглядящая (это все еще актуально?) Версия:
(Да,
Map#set
возвращает ссылку на карту. Некоторые утверждают, что это неправомерное использованиеreduce
.)Или мы можем действительно перейти на топ на неизвестность:
Нет, я бы никогда этого не сделал. :-)
источник
var buildMap2 = o => new Map(Object.keys(o).map(k => [k, o[k]]));
.new Map(Object.entries(object))
Stackoverflow.com/a/36644558/798133Нет, достаточно итератора массивов пар ключ-значение. Чтобы избежать создания промежуточного массива, можно использовать следующее:
источник
if(!obj.hasOwnProperties(key)) continue;
сразу после условия цикла for, чтобы гарантировать, что вы не получите свойства, унаследованные от прототипа объекта (если вы не доверяете объекту, но должны делать это в любом случае при повторении объектов с использованиемin
как хорошая привычка)..hasOwnProperty
собственность, и вам придется использоватьObject.prototype.hasOwnProperty.call(obj, key)
call
.obj.hasOwnProperties(key)
Кажется, что все рекомендующие соглашения не имеют ни малейшего представления о том, что делают.Object
в aMap
- дорогостоящая операция, и OP специально попросил решение без промежуточных продуктов. Так почему же это не исключительный ответ? Что ж, спрашивать об этом, наверное, бесполезно, это меня просто раздражает.function* entries<T>(obj: T): Generator<readonly [keyof T, T[keyof T]]> {…}
. Такжеyield [key, obj[key]] as const;
поможет TypeScript понять, что он генерирует кортежи, а не массивы.Ответ Нильса описывает, как преобразовывать объекты в карты, что мне показалось очень полезным. Однако OP также задавался вопросом, где эта информация находится в документах MDN. Хотя его могло и не быть, когда вопрос был первоначально задан, теперь он находится на странице MDN для Object.entries () под заголовком Преобразование объекта в карту, в котором говорится:
источник
источник
var buildMap2 = o => new Map(Object.keys(o).map(k => [k, o[k]]));
.В качестве альтернативы вы можете использовать метод lodash toPairs :
источник
ES6
преобразовать объект в карту:
преобразовать карту в объект:
Примечание: функция mapToObj предполагает, что ключи карты являются строками (в противном случае не удастся)
источник
С помощью некоторого JQuery,
источник