Як конвертувати ключі Map у масив?


237

Скажімо, у мене є така карта:

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

І я хочу отримати ['a', 'b'] виходячи з вищезазначеного. Моє сьогоднішнє рішення здається таким довгим і жахливим.

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

Повинен бути кращий шлях, ні?


17
Може бути Array.from(Map.keys()).
Ден Д.


5
@gK. Це не працює Map.
pawel

@pawel О, вибачте тоді!
hamnix

Array.from(Map.values())- якщо у випадку вам потрібні значення, а не ключі.
Манохар Редді Поредді

Відповіді:


436

Map.keys()повертає MapIteratorоб'єкт, який можна перетворити на Arrayвикористання Array.from:

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

EDIT: ви також можете перетворити ітерабельний об'єкт у масив, використовуючи синтаксис розширення

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

6
Мені подобається використання оператора Spread, однак мій транспілер TypeScript кидає this.map.values().slice is not a function. Можливо, я повинен оновити.
Коді

4
@Cody це тому, що ваша slice()виклик виконується перед оператором розповсюдження. Спробуйте[ ... Array.from(map.values()).slice(0) ]
mgthomas99

5
TypeScript 2.7.2 говорить про це: const fooMap = new Map<number, string>(); const fooArray = [...fooMap.keys()];наступне: TS2461: Тип 'IterableIterator <номер>' - це не тип масиву. Тому це не дозволяється в TypeScript. Array.from працює як очікувалося.
Стефан Рейн

Оператор розширення @StefanRein Typescript виглядає таким же, але не еквівалентний розвороту ES6, оскільки він працює лише з типами масивів і об'єктів, тоді як ES6 працює з будь-яким ітерабельним. Ви можете, наприклад, зробити, ..."abc"щоб потрапити ["a","b","c"]в ES6, що неможливо в TS.
pawel

@pawel ..."abc"ні ...("abc")працюють у хромованій консолі, яка підтримує ES6?
Стефан Рейн


6

Array.from(myMap.keys()) не працює в сценаріях програми Google.

Спроба використовувати його призводить до помилки TypeError: Cannot find function from in object function Array() { [native code for Array.Array, arity=1] } .

Щоб отримати список ключів у GAS, виконайте це:

var keysList = Object.keys(myMap);

Цей для мене працює, і перша відповідь не відповіла. Я не використовую Google ... але я постійно отримував помилку, кажучи, що map.keys()повернене значення не піддається.
Azurespot

5

Мені потрібно щось подібне з кутовою реактивною формою:

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

Не зовсім найкраща відповідь на питання, але цей трюк new Array(...someMap)врятував мене кілька разів, коли мені потрібні і ключ, і значення для створення необхідного масиву. Наприклад, коли є необхідність створити компоненти реагування з об’єкта Map на основі значень ключа та значення.

  let map = new Map();
  map.set("1", 1);
  map.set("2", 2);
  console.log(new Array(...map).map(pairs => pairs[0])); -> ["1", "2"]

1

Гаразд, давайте трохи детальніше і почнемо з того, що Карта для тих, хто не знає цієї функції в JavaScript ... MDN говорить:

Об'єкт Map містить пари "ключ-значення" і запам'ятовує початковий порядок вставки ключів.
Будь-яке значення (як об'єкти, так і примітивні значення) може використовуватися як ключ або значення.

Як ви вже згадували, ви можете легко створити екземпляр Map за допомогою нового ключового слова ... У вашому випадку:

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

Тож побачимо ...

Спосіб, який ви згадали, це нормальний спосіб зробити це, але так, є більш стислі способи зробити це ...

Карта має безліч методів, якими ви можете скористатися, наприклад, set()ви вже використовували для призначення ключових значень ...

Один з них - це те, keys()що повертає всі ключі ...

У вашому випадку він поверне:

MapIterator {"a", "b"}

і ви легко перетворите їх у масив, використовуючи ES6 способами, як-от оператор розповсюдження ...

const b = [...myMap.keys()];
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.