Z jakiegoś powodu nie mogę znaleźć tej prostej rzeczy w dokumentacji MDN (może po prostu jej brakuje).
Spodziewałem się, że to zadziała:
const map = new Map({foo: 'bar'});
map.get('foo'); // 'bar'
... ale pierwsza linia rzuca TypeError: (var)[Symbol.iterator] is not a function
Jak zrobić mapę ze zwykłego obiektu? Czy naprawdę muszę najpierw przekonwertować go na tablicę tablic par klucz-wartość?
javascript
ecmascript-6
callum
źródło
źródło
Object.entries
naprawdę jest lepszym podejściemObject.keys
, a podejście do funkcji generatora Bergi jest nieco bardziej bezpośrednie niż alboObject.keys
alboObject.entries
.Odpowiedzi:
Tak,
Map
konstruktor przyjmuje tablicę par klucz-wartość.Object.entries
jest nową metodą statyczną Object dostępną w ES2017 (19.1.2.5) .Obecnie jest zaimplementowany w przeglądarkach Firefox 46+ i Edge 14+ oraz nowszych wersjach Chrome
Jeśli potrzebujesz obsługi starszych środowisk, a transpilacja nie jest dla Ciebie opcją, użyj polyfill, takiego jak zalecany przez Georg:
źródło
Object.entries = obj => Object.keys(obj).map(k => [k, obj[k]])
Object.entries
wylądował w Node 7.x właściwym (bez flagi) btwZobacz odpowiedź nilsa przy użyciu
Object.entries
i / lub odpowiedź Bergi za pomocą funkcji generatora . ChociażObject.entries
nie było jeszcze w specyfikacji, gdy zadawano pytanie, było na etapie 4 , więc można go bezpiecznie wypełnić i używać nawet w kwietniu 2016 r. (Właśnie). (Więcej o etapach tutaj .) A funkcje generatora były w ES2015. Program operacyjny wyraźnie poprosił o unikanie pośredników i chociaż generator nie unika tego całkowicie, wykonuje lepszą pracę niż poniżej lub (nieznacznie)Object.enties
.FWIW, używając
Object.entries
:[name, value]
tablic do przekazanianew Map
Map
Konstruktor wywołuje funkcję na tablicy, aby uzyskać iterator; tablica tworzy i zwraca obiekt pośredniczący tablicy.Map
zastosowania konstruktor iterator obiektu, aby uzyskać dane (The[name, value]
tablice) i zbudować mapęKorzystanie z generatora:
Map
Konstruktor wywołuje funkcję na tym obiekcie generatora dostać iterator od niego; obiekt generatora zwraca sam siebieMap
Konstruktor używa obiektu generatora (jako iterator), aby uzyskać wpisy (te[name, value]
tablice) i zbudować mapęA więc: o jeden pośrednik mniej (tablica z
Object.entries
).Jednak używanie
Object.entries
jest prostsze, a tworzenie tej tablicy nie stanowi problemu w 99,999% przypadków. Więc naprawdę, albo jeden. Ale oba są lepsze niż poniżej. :-)Oryginalna odpowiedź:
Aby zainicjować a
Map
, możesz użyć dowolnego iteratora, który zwraca pary klucz / wartość jako tablice, takie jak tablica tablic:Nie ma wbudowanej konwersji z obiektu na mapę, ale można to łatwo zrobić za pomocą
Object.keys
:Możesz oczywiście przypisać sobie funkcję pracownika, aby sobie z tym poradzić:
Następnie
Lub tutaj jest wersja bardziej wyglądająca na l33t (czy to wciąż coś?):
(Tak,
Map#set
zwraca odniesienie mapy. Niektórzy twierdzą, że jest to abusage zreduce
).Lub możemy naprawdę przesadzić w kwestii niejasności:
Nie, nigdy bym tego naprawdę nie zrobił. :-)
źródło
var buildMap2 = o => new Map(Object.keys(o).map(k => [k, o[k]]));
.new Map(Object.entries(object))
stackoverflow.com/a/36644558/798133Nie, wystarczy iterator tablic par klucz-wartość. Aby uniknąć tworzenia tablicy pośredniej, możesz użyć następujących czynności:
źródło
if(!obj.hasOwnProperties(key)) continue;
zaraz po warunku pętli for, aby upewnić się, że nie otrzymasz właściwości odziedziczonych z prototypu obiektu (chyba że ufasz obiektowi, ale powinieneś to zrobić mimo wszystko podczas iteracji obiektów przy użyciuin
jako dobry nawyk)..hasOwnProperty
własności i musiałbyś z niego korzystaćObject.prototype.hasOwnProperty.call(obj, key)
call
.obj.hasOwnProperties(key)
Wydaje się, że wszystkie konwencje, które zalecają , nie mają pojęcia, co robią.Object
wMap
jest kosztowną operacją, a OP specjalnie poprosił o rozwiązanie bez półproduktów. Dlaczego więc nie jest to wyjątkowa odpowiedź? Cóż, pytanie o to jest prawdopodobnie bezcelowe, po prostu mnie denerwuje.function* entries<T>(obj: T): Generator<readonly [keyof T, T[keyof T]]> {…}
.yield [key, obj[key]] as const;
Pomogłoby również TypeScript uświadomić sobie, że generuje krotki, a nie tablice.Odpowiedź Nilsa opisuje, jak konwertować obiekty na mapy, co okazało się bardzo przydatne. Jednak PO zastanawiał się również, gdzie znajdują się te informacje w dokumentach MDN. Chociaż mogło go tam nie być, gdy pierwotnie zadawano pytanie, jest teraz na stronie MDN dla Object.entries () pod nagłówkiem Converting an Object to a Map, który stwierdza:
źródło
źródło
var buildMap2 = o => new Map(Object.keys(o).map(k => [k, o[k]]));
.Alternatywnie możesz użyć metody lodash toPairs :
źródło
ES6
konwertuj obiekt na mapę:
przekonwertuj mapę na obiekt:
Uwaga: funkcja mapToObj zakłada, że klucze mapy są ciągami (w przeciwnym razie nie powiedzie się)
źródło
Z pomocą JQuery,
źródło