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?


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"]

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


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);

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');

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"]

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()];
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.