Jak przekonwertować klucze mapy na tablicę?

237

Powiedzmy, że mam następującą mapę:

let myMap = new Map().set('a', 1).set('b', 2);

I chcę uzyskać ['a', 'b'] w oparciu o powyższe. Moje obecne rozwiązanie wydaje się tak długie i okropne.

let myMap = new Map().set('a', 1).set('b', 2);
let keys = [];
for (let key of myMap)
  keys.push(key);
console.log(keys);

Musi być lepszy sposób, nie?

Lilleman
źródło
17
Być może Array.from(Map.keys()).
Dan D.
5
@gK. To nie działa z Map.
pawel
@pawel Oh przepraszam!
hamnix
Array.from(Map.values())- jeśli tak, potrzebujesz wartości zamiast kluczy.
Manohar Reddy Poreddy

Odpowiedzi:

436

Map.keys()zwraca MapIteratorprzedmiot, który może być przekształcony Arrayza pomocą Array.from:

let keys = Array.from( myMap.keys() );
// ["a", "b"]

EDYCJA: można także przekonwertować obiekt iterowalny na tablicę przy użyciu składni rozproszonej

let keys =[ ...myMap.keys() ];
// ["a", "b"]
pawel
źródło
6
Jednak podoba mi się użycie operatora rozprzestrzeniania, rzuca mój transpiler TypeScript this.map.values().slice is not a function. Może powinienem zaktualizować.
Cody
4
@Cody, ponieważ Twoje slice()wywołanie jest wykonywane przed operatorem rozkładania. Spróbuj[ ... Array.from(map.values()).slice(0) ]
mgthomas99
5
TypeScript 2.7.2 mówi w tym const fooMap = new Map<number, string>(); const fooArray = [...fooMap.keys()];celu: TS2461: Typ „IterableIterator <numer>” nie jest typem tablicy. Dlatego nie jest to dozwolone w TypeScript. Array.from działa zgodnie z oczekiwaniami.
Stefan Rein
@StefanRein Operator rozkładania czcionek wygląda tak samo, ale nie jest równoważny rozkładowi ES6, ponieważ działa tylko z typami macierzy i obiektów, podczas gdy ES6 działa z każdym iterowalnym. Możesz np. Zrobić, ..."abc"aby dostać się ["a","b","c"]do ES6, co nie jest możliwe w TS.
pawel
@pawel ..."abc"ani ...("abc")nie działają w konsoli Chrome, która obsługuje ES6?
Stefan Rein
15

Za pomocą operatora rozkładania można przekonwertować iterator Map.keys () na macierz.

let myMap = new Map().set('a', 1).set('b', 2).set(983, true)
let keys = [...myMap.keys()]
console.log(keys)

Fernando Carvajal
źródło
6

Array.from(myMap.keys()) nie działa w skryptach aplikacji Google.

Próba użycia powoduje błąd TypeError: Cannot find function from in object function Array() { [native code for Array.Array, arity=1] }.

Aby uzyskać listę kluczy w GAS, wykonaj następujące czynności:

var keysList = Object.keys(myMap);
Joman68
źródło
Ten działa dla mnie, a pierwsza odpowiedź nie. Nie używam Google ... ale ciągle map.keys()pojawia się błąd informujący, że zwracana wartość nie jest iterowalna.
Azurespot
5

Potrzebuję czegoś podobnego do kątowej formy reaktywnej:

let myMap = new Map().set(0, {status: 'VALID'}).set(1, {status: 'INVALID'});
let mapToArray = Array.from(myMap.values());
let isValid = mapToArray.every(x => x.status === 'VALID');
linfluX
źródło
2

Nie do końca najlepsza odpowiedź na pytanie, ale ta sztuczka new Array(...someMap)uratowała mnie kilka razy, gdy potrzebuję zarówno klucza, jak i wartości, aby wygenerować potrzebną tablicę. Na przykład, gdy trzeba utworzyć komponenty reagujące z obiektu mapy na podstawie wartości klucza i wartości.

  let map = new Map();
  map.set("1", 1);
  map.set("2", 2);
  console.log(new Array(...map).map(pairs => pairs[0])); -> ["1", "2"]
Tkoma
źródło
1

OK, przejdźmy trochę bardziej kompleksowo i zacznijmy od tego, co jest Mapą dla tych, którzy nie znają tej funkcji w JavaScript ... MDN mówi:

Obiekt Map przechowuje pary klucz-wartość i zapamiętuje pierwotną kolejność wstawiania kluczy.
Każda wartość (zarówno obiekty, jak i wartości pierwotne) może być używana jako klucz lub wartość.

Jak wspomniałeś, możesz łatwo utworzyć instancję mapy, używając nowego słowa kluczowego ... W twoim przypadku:

let myMap = new Map().set('a', 1).set('b', 2);

Zobaczmy więc ...

Wspomniany sposób jest w porządku, ale tak, są bardziej zwięzłe sposoby na zrobienie tego ...

Mapa ma wiele metod, których można użyć, takich jak set()te, które zostały już użyte do przypisania kluczowych wartości ...

Jednym z nich jest keys()zwrócenie wszystkich kluczy ...

W twoim przypadku zwróci:

MapIterator {"a", "b"}

i łatwo przekształcasz je w macierz przy użyciu metod ES6 , takich jak operator spread ...

const b = [...myMap.keys()];
Alireza
źródło