¿Cómo convertir teclas de mapa a matriz?

237

Digamos que tengo el siguiente mapa:

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

Y quiero obtener ['a', 'b'] basado en lo anterior. Mi solución actual parece tan larga y horrible.

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

Debe haber una mejor manera, ¿no?

Lilleman
fuente
17
Tal vez Array.from(Map.keys()).
Dan D.
55
@G k. No funciona con Map.
Pawel
@pawel Oh, lo siento, entonces!
hamnix
Array.from(Map.values())- en caso de que necesite valores, en lugar de claves.
Manohar Reddy Poreddy

Respuestas:

436

Map.keys()devuelve un MapIteratorobjeto que se puede convertir Arrayusando Array.from:

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

EDITAR: también puede convertir objetos iterables en matriz utilizando sintaxis extendida

let keys =[ ...myMap.keys() ];
// ["a", "b"]
pawel
fuente
66
Sin embargo, me gusta el uso del Operador Spread, mi transpiler TypeScript arroja this.map.values().slice is not a function. Tal vez debería actualizar.
Cody
44
@Cody es porque su slice()invocación se está ejecutando antes que el operador de propagación. Prueba[ ... Array.from(map.values()).slice(0) ]
mgthomas99
55
TypeScript 2.7.2 dice para esto: const fooMap = new Map<number, string>(); const fooArray = [...fooMap.keys()];lo siguiente: TS2461: El tipo 'IterableIterator <número>' no es un tipo de matriz. Entonces esto no está permitido en TypeScript. Array.from funciona como se esperaba.
Stefan Rein
@StefanRein El operador de propagación mecanografiada se ve igual, pero no es equivalente a la propagación ES6, ya que solo funciona con los tipos Array y Object, mientras que ES6 funciona con cualquier iterable. Puede, por ejemplo, hacer ..."abc"para obtener ["a","b","c"]ES6, que no es posible en TS.
pawel
@pawel ..."abc"tampoco ...("abc")está trabajando en la consola de Chrome, que es compatible con ES6?
Stefan Rein
15

Puede usar el operador de propagación para convertir el iterador Map.keys () en una matriz.

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

Fernando Carvajal
fuente
6

Array.from(myMap.keys()) no funciona en scripts de aplicaciones de google.

Intentar usarlo da como resultado el error TypeError: Cannot find function from in object function Array() { [native code for Array.Array, arity=1] }.

Para obtener una lista de claves en GAS, haga esto:

var keysList = Object.keys(myMap);
Joman68
fuente
Este funciona para mí, y la primera respuesta no. No estoy usando Google ... pero recibí un error diciendo que el map.keys()valor de retorno no es iterable.
Azurespot
5

Necesito algo similar con forma reactiva angular:

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
fuente
2

No es exactamente la mejor respuesta a la pregunta, pero este truco new Array(...someMap)me salvó un par de veces cuando necesito clave y valor para generar la matriz necesaria. Por ejemplo, cuando es necesario crear componentes de reacción a partir del objeto Map basado en valores clave y de valor.

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

OK, vamos a ser un poco más completos y comencemos con lo que es Map para aquellos que no conocen esta función en JavaScript ... MDN dice:

El objeto Map contiene pares clave-valor y recuerda el orden de inserción original de las claves.
Cualquier valor (tanto objetos como valores primitivos) se puede usar como clave o como valor.

Como mencionó, puede crear fácilmente una instancia de Map usando una nueva palabra clave ... En su caso:

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

Entonces veamos ...

La forma en que mencionó es una buena manera de hacerlo, pero sí, hay formas más concisas de hacerlo ...

Map tiene muchos métodos que puede usar, como los set()que ya utilizó para asignar los valores clave ...

Uno de ellos es el keys()que devuelve todas las llaves ...

En su caso, devolverá:

MapIterator {"a", "b"}

y los convierte fácilmente en una matriz utilizando formas ES6 , como el operador de propagación ...

const b = [...myMap.keys()];
Alireza
fuente