Как преобразовать ключи карты в массив?

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 Ой, прости!
Hamnix
Array.from(Map.values())- если в этом случае вам нужны значения, а не ключи.
Манохар Редди Поредди

Ответы:

436

Map.keys()возвращает MapIteratorобъект, который может быть преобразован в Arrayиспользование Array.from:

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

РЕДАКТИРОВАТЬ: вы также можете конвертировать повторяемый объект в массив, используя синтаксис распространения

let keys =[ ...myMap.keys() ];
// ["a", "b"]
Pawel
источник
6
Мне нравится использование Spread Operator, хотя мой бросок транспортера TypeScript this.map.values().slice is not a function. Может быть, я должен обновить.
Коди
4
@ Коди, это потому, что ваш 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, поскольку он работает только с типами Array и Object, тогда как ES6 работает с любыми итерациями. Вы можете, например, сделать, ..."abc"чтобы получить ["a","b","c"]в ES6, что невозможно в TS.
Павел
@pawel ..."abc"и ...("abc")не работают в консоли Chrome, которая поддерживает ES6?
Стефан Рейн
15

Вы можете использовать оператор распространения для преобразования итератора Map.keys () в массив.

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

Фернандо Карвахаль
источник
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);
Joman68
источник
Этот работает для меня, и первый ответ не. Я не пользуюсь 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');
linfluX
источник
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"]
Tkoma
источник
1

Хорошо, давайте немного подробнее и начнем с того, что такое Map для тех, кто не знает эту функцию в JavaScript ... MDN говорит:

Объект Map содержит пары ключ-значение и запоминает исходный порядок вставки ключей.
Любое значение (как объекты, так и примитивные значения) может использоваться в качестве ключа или значения.

Как вы упомянули, вы можете легко создать экземпляр Map, используя новое ключевое слово ... В вашем случае:

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

Итак, посмотрим ...

То, как вы упомянули, - это хороший способ сделать это, но да, есть более краткие способы сделать это ...

В Map есть много методов, которые вы можете использовать, например, set()которые вы уже использовали для назначения значений ключей ...

Одним из них является то, keys()что возвращает все ключи ...

В вашем случае он вернет:

MapIterator {"a", "b"}

и вы легко конвертируете их в массив, используя способы ES6 , такие как оператор распространения ...

const b = [...myMap.keys()];
Алиреза
источник