admin管理员组

文章数量:1206201

I can use a Map and then set values:

const a = new Map([["a", "b"], ["c", "d"]])

Now if I want to apply a function to all values in a functional way (without for ... of or .forEach), I thought I could have done something like this:

const b = a.map(([k, v]) => [k, doSomethingWith(v)]);

But there is no map function on a Map. Is there a built-in/elegant way to map a Map?

I can use a Map and then set values:

const a = new Map([["a", "b"], ["c", "d"]])

Now if I want to apply a function to all values in a functional way (without for ... of or .forEach), I thought I could have done something like this:

const b = a.map(([k, v]) => [k, doSomethingWith(v)]);

But there is no map function on a Map. Is there a built-in/elegant way to map a Map?

Share Improve this question edited Apr 24, 2019 at 10:26 Peter Mortensen 31.6k22 gold badges109 silver badges133 bronze badges asked Apr 24, 2019 at 8:56 rap-2-hrap-2-h 31.9k46 gold badges186 silver badges280 bronze badges 4
  • Use Map#entries then .map on them a.entries().map(...) – ponury-kostek Commented Apr 24, 2019 at 9:02
  • @ponury-kostek It won't work because Map.entries() return an Iterator (not Array); and Iterators haven't .map method... – FZs Commented Apr 24, 2019 at 9:10
  • Unfortunately, there is no elegant way. You have to process the entries and then produce a new Map out of the result. – VLAZ Commented Apr 24, 2019 at 9:11
  • Possible duplicate of Using map/filter behavior on Map instance – Bergi Commented Apr 24, 2019 at 13:57
Add a comment  | 

6 Answers 6

Reset to default 11

You could use Array.from for getting entries and mapping new values and take this result for a new Map.

const b = new Map(Array.from(
    a, 
    ([k, v]) => [k, doSomethingWith(v)]
));

The most elegant/concise way I am aware of is by converting the map to an array with the spread operator (...), applying .map to that array and then creating a Map from it again:

const a = new Map([["a", "b"], ["c", "d"]])
const b = new Map([...a].map(([k,v])=>[k, v.toUpperCase()]))
// b: Map(2) {"a" => "B", "c" => "D"}

There are no builtin methods for this (yet!). The most elegant way currently is to use generators:

const b = new Map((function*() {
    for (const [k, v] of a)
        yield [k, doSomethingWith(v)];
})());

I would however recommend to write helper functions for this that work with arbitrary iterables:

function* mapValue(iterable, callback) {
    for (const [k, v] of a)
        yield [k, callback(v)];
}
const b = new Map(mapValue(a, doSomethingWith));

You could use Symbol.iterator for changing or creating a new Map.

function f (iterator) {
  for (let item of iterator1) {
    item[0] = 1;
    item[1] = 'hello world';
    console.log(item);
  }
}

var map1 = new Map();
map1.set('0', 'foo');
map1.set(1, 'bar');
var iterator1 = map1[Symbol.iterator]();

f(iterator1);

You could do that like this:

let b = new Map(a)
b.forEach((value,key,myMap) => myMap.set(key, dosomething(value)))

or:

let b
(b = new Map(a)).forEach((value,key,myMap) => myMap.set(key, dosomething(value)))

For comparison (& because these methods were a little ugly..), here's how to modify each value of a map using a traditional for .. of loop:

for (let entry of map.entries()) {
  let key = entry[0], value = entry[1];
  let newValue = value + ' '; // Modify however.
  map.set(key, newValue);
}

本文标签: javascriptUsing a map function on a 39Map39 to change valuesStack Overflow