如何在 Javascript 中的 Map 键上使用 .map()

Posted

技术标签:

【中文标题】如何在 Javascript 中的 Map 键上使用 .map()【英文标题】:How to use .map() over Map keys in Javascript 【发布时间】:2019-12-29 17:05:13 【问题描述】:

当使用 Map 内置的 javascript 时,如何使用 .map() 来遍历键?

我知道for...of可以如下所示使用:

const map = new Map();

map.set(0, 'Zero');
map.set(1, 'One');
map.set(2, 'Two');

for (let key of map.keys()) 
  console.log(key);

但是这段代码会失败:

map.keys().map(key => 
  console.log(key);
);

【问题讨论】:

【参考方案1】:

你可以使用Array.from():

const map = new Map();

map.set(0, 'Zero');
map.set(1, 'One');
map.set(2, 'Two');

Array.from(map.keys()).map(key => 
  console.log(key);
);

希望对您有所帮助!

【讨论】:

【参考方案2】:

其实是Array.prototype.map,是为数组定义的,所以用Array.fromkeys转成数组再用map

const map = new Map();

map.set(0, 'Zero');
map.set(1, 'One');
map.set(2, 'Two');

Array.from(map.keys()).map(key => 
  console.log(key);
);

【讨论】:

【参考方案3】:

您最好直接使用Array.from 映射函数以避免创建临时数组:

Array.from(map.keys(), k => console.log(k))

另一个更详细但有用的选项是在迭代器原型上重新定义数组迭代方法,从而使它们自动可用于所有迭代器:

// http://www.ecma-international.org/ecma-262/7.0/#sec-%iteratorprototype%-object
const IteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()));

Object.defineProperties(IteratorPrototype, 
    forEach: 
        value: function (fn) 
            let n = 0;

            for (let x of this) 
                fn(x, n++, this);
            
        ,
        enumerable: false
    ,
    
    map: 
        value: function (fn) 
            let n = 0, a = [];

            for (let x of this) 
                a.push(fn(x, n++, this));
            

            return a;
        ,
        enumerable: false
    ,
    
    reduce: 
        value: function (fn, init) 
            let n = 0;

            if (arguments.length === 1) 
                init = this.next().value;
            

            for (let x of this) 
                init = fn(init, x, n++, this);
            

            return init;
        ,
        enumerable: false
    ,

);


/////

const map = new Map();

map.set('a', 'Zero');
map.set('b', 'One');
map.set('c', 'Two');

map.keys().map(console.log)

console.log(map.values().reduce((o, k) => o + '/' + k));

function* it() 
    yield 'x';
    yield 'y';
    yield 'z';


it().map(x => console.log(x))

【讨论】:

【参考方案4】:

Map.keys() 返回一个迭代器,您可以使用 spread syntax 传播迭代器

const map = new Map();

map.set(0, 'Zero');
map.set(1, 'One');
map.set(2, 'Two');

[...map.keys()].forEach(key => 
  console.log(key);
)

【讨论】:

使用for..of时无需传播,因为它已经符合迭代器协议。 @georg 哎呀我的错!!,我的意思是传播然后使用任何数组方法,已更新,感谢指出【参考方案5】:

map.forEach((_,key) => console.log(key));

【讨论】:

【参考方案6】:

正如其他答案所指出的,map 是一个Array 方法,因此您必须先将map.keys() 返回的可迭代对象转换为数组。这比使用for 循环效率低,因为不需要转换。在library 中,我写过一个函数,它可以将一个可迭代对象映射到另一个可迭代对象,而无需创建数组:

export const mapIterable = <From, To>(project: (value: From) => To) =>
  function* (iterable: Iterable<From>): IterableIterator<To> 
    for (const value of iterable) 
      yield project(value);
    
  ;

你通常使用a ponyfill for the pipeline operator。

【讨论】:

以上是关于如何在 Javascript 中的 Map 键上使用 .map()的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ME51n tcode 中的项目级别上使自定义字段可编辑?

如何在 pyspark 中的多个键上使用 GroupByKey?

使用 javascript 在 Enter 键上提交表单

如何在 Sprite 套件中的返回键上隐藏键盘?

Richfaces 列过滤器:如何在介绍键上触发事件

如何在 vuetify 上使标题栏动态化?