JavaScript ES2015中从Map中获取第一个元素

92

我有一个像这样的 Map

const m = new Map();
m.set('key1', {})
.
m.set('keyN' {})

Map可以有1个或多个元素。我能否通过索引获取第一个元素,而不使用m.get('key1')和迭代循环呢?

例如:m.values().next().value


7
Map(映射)按照插入顺序迭代其元素,而对象的迭代顺序没有指定。 - Philip Loger
5个回答

157
使用 Map.prototype.entries 函数,就像这样:

const m = new Map();
m.set('key1', {})
m.set('keyN', {})

console.log(m.entries().next().value); // [ 'key1', {} ]


如果你想获取第一个键,那么可以使用Map.prototype.keys,就像这样。
console.log(m.keys().next().value); // key1

同样地,如果你想获取第一个值,那么你可以使用 Map.prototype.values,像这样。
console.log(m.values().next().value); // {}

我们为什么必须在返回的值上调用next(),因为所有这些函数都返回迭代器。在这里阅读更多关于迭代协议的信息。

2
你为什么要更改 OP 使用的 'keyN' 键? - Bergi
最后一个键/值怎么样? - Alexander Mills
是否可以用另一个条目替换第一个条目?例如上面的示例,我是否可以用 key3:{val: 3} 替换条目 key1: {},而不必创建一个新的 Map? - darKnight

24

对于您所关注的特定示例,解构将是完美的选择。

let m = new Map();
m.set('key1', {});
m.set('key2', {});

let [[, obj]] = m;
例如。
let [pair] = m;
let [key, obj] = pair;

使用解构并获取值是一种选项,但更简单的选项是

let [obj] = m.values();

12

也可以使用ES6及其后续版本的展开操作符完成。我们先声明一个新的Map变量,然后添加两个值。 之后,我们将使用 ... 将map转换为数组或者您可以使用Array.from,然后只需在获取到的数组上使用[0]即可获得第一个元素。

const m = new Map();
m.set('key1', 1);
m.set('key2', 2);

console.log([...m][0]);    // ['key1', 1] 

或者可以使用 JavaScript 数组的 destruct 特性,快速地将 [k, v] 数组指向 map 的第一项。

const [[k, v]] = m;
console.log(k, v); // 'key1', 1

在这个网站上,仅提供代码的答案通常不被看好。您能否编辑您的答案,包括一些注释或解释您的代码?解释应该回答以下问题:它是做什么的?它是如何做到的?它去哪里?它是如何解决 OP 的问题的?请参阅:如何回答。谢谢! - Eduardo Baitello
你正在将它转换为一个数组,然后显示第一个元素。 - dota2pro

9

同样适用于SetMap:你可以将任何东西转换为Array,然后通过索引获取其中的任何元素。像这样:

const m = new Map();
m.set('key1', {});
m.set('key2', {});

console.log(Array.from(m)[0]); // ['key1', {}]


3
因为它会从映射中创建一个新的数组,所以这个版本太贵了。 - thomas

3

对于所有可迭代对象,您可以使用迭代器 object[Symbol.iterator]()

在我们的情况下,如上面MDN页面所述,这将指向entries()方法:

默认情况下是 map 迭代器函数,也就是 entries() 函数。

const m = new Map();
m.set('key1', {})
m.set('keyN', {})

console.log(m[Symbol.iterator]().next().value); // [ 'key1', {} ]

以下是翻译的结果:

下面是所有解决方案的基准测试结果: https://jsbench.me/9fkpm6q9y0/1

entries()版本获胜,但与迭代器版本非常接近。这是合理的,因为[Symbol.iterator]()调用了entries()


2
我认为.entries().next().value比使用Symbol.iterator更易读,但我为你实际进行基准测试的解决方案点赞。我注意到一件事:let [pair] = map;只比entries/iterator慢16%,而let [[key, val]] = map;慢33%--分配额外的“双重解构”匿名数组需要时间。 - Coderer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接