วิธีแปลงคีย์แผนที่เป็นอาเรย์?


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())บางที
Dan D.


5
@gK Mapมันไม่ได้ทำงานกับ
pawel

@pawel โอ้ขอโทษแล้ว!
hamnix

Array.from(Map.values())- หากในกรณีที่คุณต้องการค่าแทนที่จะเป็นกุญแจ
Manohar Reddy Poreddy

คำตอบ:


436

Map.keys()ส่งคืนMapIteratorวัตถุซึ่งสามารถแปลงเป็นArrayโดยใช้Array.from:

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

แก้ไข: คุณยังสามารถแปลงออบเจกต์ iterable เป็น array โดยใช้สเปรดไวยากรณ์

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

6
ผมชอบการใช้งานของผู้ประกอบการแพร่กระจายแม้ว่า transpiler 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: Type 'IterableIterator <number>' ไม่ใช่ประเภทอาเรย์ ดังนั้นสิ่งนี้ไม่ได้รับอนุญาตใน TypeScript Array.from ทำงานตามที่คาดไว้
Stefan Rein

@StefanRein Typescript spread operator ดูเหมือนกัน แต่ไม่เทียบเท่ากับการแพร่กระจาย ES6 เนื่องจากใช้ได้เฉพาะกับ Array และประเภทวัตถุในขณะที่ ES6 ทำงานร่วมกับ iterable ใด ๆ คุณสามารถทำเช่นนั้น..."abc"เพื่อรับ["a","b","c"]ใน ES6 ซึ่งเป็นไปไม่ได้ใน TS
pawel

@pawel ..."abc"และไม่...("abc")ทำงานในคอนโซล Chrome ซึ่งสนับสนุน ES6?
สเตฟาน Rein


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)ช่วยฉันสองสามครั้งเมื่อฉันต้องการทั้งคีย์และค่าเพื่อสร้างอาร์เรย์ที่ต้องการ ตัวอย่างเช่นเมื่อมีความจำเป็นต้องสร้างองค์ประกอบการตอบสนองจากวัตถุแผนที่ขึ้นอยู่กับทั้งค่าคีย์และค่า

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

1

ตกลงกันเถอะให้ครอบคลุมมากขึ้นและเริ่มต้นด้วยMapคืออะไรสำหรับผู้ที่ไม่รู้จักคุณสมบัตินี้ใน JavaScript ... MDN พูดว่า:

วัตถุแผนที่ถือคู่ค่าคีย์และจดจำลำดับการแทรกดั้งเดิมของคีย์
ค่าใด ๆ (ทั้งวัตถุและค่าดั้งเดิม) อาจใช้เป็นคีย์หรือค่า

ดังที่คุณกล่าวถึงคุณสามารถสร้างตัวอย่างของแผนที่โดยใช้คำหลักใหม่ ... ในกรณีของคุณ:

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

ดังนั้นเรามาดู ...

วิธีที่คุณกล่าวถึงเป็นวิธีที่ทำได้ แต่ใช่มีวิธีรัดกุมมากกว่าในการทำเช่นนั้น ...

แผนที่มีวิธีการมากมายที่คุณสามารถใช้ได้เช่นset()ที่คุณเคยใช้ในการกำหนดค่าคีย์ ...

หนึ่งในนั้นคือkeys()ที่ส่งคืนกุญแจทั้งหมด ...

ในกรณีของคุณมันจะกลับมา:

MapIterator {"a", "b"}

และคุณสามารถแปลงเป็น Array ได้อย่างง่ายดายโดยใช้วิธีES6เช่นตัวดำเนินการแพร่กระจาย ...

const b = [...myMap.keys()];
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.