你会怎么做?本能地,我想做:
var myMap = new Map([["thing1", 1], ["thing2", 2], ["thing3", 3]]);
// wishful, ignorant thinking
var newMap = myMap.map((key, value) => value + 1); // Map { 'thing1' => 2, 'thing2' => 3, 'thing3' => 4 }
我还没有从documentation on the new iteration protocol收集到太多信息。
我知道wu.js,但我正在运行Babel项目,并且不想包含Traceur,it seems like it currently depends on。
关于如何将how fitzgen/wu.js did it提取到我自己的项目中,我也有点无能为力。
我希望能够清楚,简洁地解释我在这里缺少的东西。谢谢!
Docs for ES6 Map,仅供参考
答案 0 :(得分:49)
所以.map
本身只提供你关心的一个值...
也就是说,有几种方法可以解决这个问题:
// instantiation
const myMap = new Map([
[ "A", 1 ],
[ "B", 2 ]
]);
// what's built into Map for you
myMap.forEach( (val, key) => console.log(key, val) ); // "A 1", "B 2"
// what Array can do for you
Array.from( myMap ).map(([key, value]) => ({ key, value })); // [{key:"A", value: 1}, ... ]
// less awesome iteration
let entries = myMap.entries( );
for (let entry of entries) {
console.log(entry);
}
注意,我在第二个例子中使用了很多新东西......
... Array.from
采用任何可迭代(任何时候你使用[].slice.call( )
,加上集合和地图)并将其转换为数组...... ...地图,当被强制转换为数组时,变成一个数组数组,其中el[0] === key && el[1] === value;
(基本上,与我在上面预填充示例Map的格式相同)。
我在lambda的参数位置使用数组的解构,在为每个el返回一个对象之前将这些数组点分配给值。
如果您正在使用Babel,在制作中,您将需要使用Babel的浏览器polyfill(其中包括" core-js"以及Facebook' s"再生器")
我很确定它包含Array.from
。
答案 1 :(得分:23)
您应该使用 Spread operator :
var myMap = new Map([["thing1", 1], ["thing2", 2], ["thing3", 3]]);
var newArr = [...myMap].map(value => value[1] + 1);
console.log(newArr); //[2, 3, 4]
var newArr2 = [for(value of myMap) value = value[1] + 1];
console.log(newArr2); //[2, 3, 4]

答案 2 :(得分:14)
只需使用Array.from(iterable, [mapFn])
。
var myMap = new Map([["thing1", 1], ["thing2", 2], ["thing3", 3]]);
var newArr = Array.from(myMap.values(), value => value + 1);
答案 3 :(得分:2)
实际上,在使用Map
转换为数组之后,您仍然可以使用原始密钥生成Array.from
。可以通过返回 array 来实现,其中第一项是key
,第二项是转换后的value
。
const originalMap = new Map([
["thing1", 1], ["thing2", 2], ["thing3", 3]
]);
const arrayMap = Array.from(originalMap, ([key, value]) => {
return [key, value + 1]; // return an array
});
const alteredMap = new Map(arrayMap);
console.log(originalMap); // Map { 'thing1' => 1, 'thing2' => 2, 'thing3' => 3 }
console.log(alteredMap); // Map { 'thing1' => 2, 'thing2' => 3, 'thing3' => 4 }
如果您没有将键作为第一个数组项返回,则松开Map
键。
答案 4 :(得分:1)
您可以使用此功能:
function mapMap(map, callback) {
return new Map(Array.from(map).map(([key, value]) => [key, callback(value, key, map)]));
}
用法:
var map1 = new Map([["A", 2], ["B", 3], ["C", 4]]);
var map2 = mapMap(map1, v => v * v);
console.log(map1, map2);
/*
Map { A → 2, B → 3, C → 4 }
Map { A → 4, B → 9, C → 16 }
*/
答案 5 :(得分:0)
const mapMap = (callback, map) => new Map(Array.from(map).map(callback))
var myMap = new Map([["thing1", 1], ["thing2", 2], ["thing3", 3]]);
var newMap = mapMap((pair) => [pair[0], pair[1] + 1], myMap); // Map { 'thing1' => 2, 'thing2' => 3, 'thing3' => 4 }

答案 6 :(得分:0)
使用Array.from
我编写了一个用于映射值的Typescript函数:
function mapKeys<T, V, U>(m: Map<T, V>, fn: (this: void, v: V) => U): Map<T, U> {
function transformPair([k, v]: [T, V]): [T, U] {
return [k, fn(v)]
}
return new Map(Array.from(m.entries(), transformPair));
}
const m = new Map([[1, 2], [3, 4]]);
console.log(mapKeys(m, i => i + 1));
// Map { 1 => 3, 3 => 5 }
答案 7 :(得分:0)
如果您不想事先将整个Map转换为数组,和/或解构键值数组,您可以使用这个愚蠢的函数:
/**
* Map over an ES6 Map.
*
* @param {Map} map
* @param {Function} cb Callback. Receives two arguments: key, value.
* @returns {Array}
*/
function mapMap(map, cb) {
let out = new Array(map.size);
let i = 0;
map.forEach((val, key) => {
out[i++] = cb(key, val);
});
return out;
}
let map = new Map([
["a", 1],
["b", 2],
["c", 3]
]);
console.log(
mapMap(map, (k, v) => `${k}-${v}`).join(', ')
); // a-1, b-2, c-3
答案 8 :(得分:0)
Map.prototype.map = function(callback) {
const output = new Map()
this.forEach((element, key)=>{
output.set(key, callback(element, key))
})
return output
}
const myMap = new Map([["thing1", 1], ["thing2", 2], ["thing3", 3]])
// no longer wishful thinking
const newMap = myMap.map((value, key) => value + 1)
console.info(myMap, newMap)
取决于你避免编辑原型的宗教热情,但是,我发现这让我保持直观。
答案 9 :(得分:0)
我更喜欢扩展地图
export class UtilMap extends Map {
constructor(...args) { super(args); }
public map(supplier) {
const mapped = new UtilMap();
this.forEach(((value, key) => mapped.set(key, supplier(value, key)) ));
return mapped;
};
}
答案 10 :(得分:0)
您可以map()数组,但是Maps没有这样的操作。 Dr. Axel Rauschmayer的解决方案:
示例:
let map0 = new Map([
[1, "a"],
[2, "b"],
[3, "c"]
]);
const map1 = new Map(
[...map0]
.map(([k, v]) => [k * 2, '_' + v])
);
产生
{2 => '_a', 4 => '_b', 6 => '_c'}
答案 11 :(得分:0)
您可以使用myMap.forEach,并在每个循环中使用map.set更改值。
myMap = new Map([
["a", 1],
["b", 2],
["c", 3]
]);
for (var [key, value] of myMap.entries()) {
console.log(key + ' = ' + value);
}
myMap.forEach((value, key, map) => {
map.set(key, value+1)
})
for (var [key, value] of myMap.entries()) {
console.log(key + ' = ' + value);
}
答案 12 :(得分:-1)
也许是这样:
const m = new Map([["a", 1], ["b", 2], ["c", 3]]);
m.map((k, v) => [k, v * 2]); // Map { 'a' => 2, 'b' => 4, 'c' => 6 }
您只需要在以下情况下猴子猴子Map
:
Map.prototype.map = function(func){
return new Map(Array.from(this, ([k, v]) => func(k, v)));
}
我们可以写出此补丁的简单形式:
Map.prototype.map = function(func){
return new Map(Array.from(this, func));
}
但是我们本来会强迫我们写m.map(([k, v]) => [k, v * 2]);
的,这对我来说似乎更痛苦和丑陋。
我们也只能映射值,但是我不建议您选择该解决方案,因为它太具体了。 不过,可以做到的,我们将拥有以下API:
const m = new Map([["a", 1], ["b", 2], ["c", 3]]);
m.map(v => v * 2); // Map { 'a' => 2, 'b' => 4, 'c' => 6 }
就像在通过这种方式进行修补之前一样:
Map.prototype.map = function(func){
return new Map(Array.from(this, ([k, v]) => [k, func(v)]));
}
也许可以同时使用两者,命名第二个mapValues
可以清楚地表明,您实际上并未像预期的那样映射对象。