.map() a Javascript ES6 Map?

前端 未结 13 2135
不思量自难忘°
不思量自难忘° 2020-12-04 20:53

How would you do this? Instinctively, I want to do:

var myMap = new Map([[\"thing1\", 1], [\"thing2\", 2], [\"thing3\", 3]]);

// wishful, ignorant thinking
         


        
相关标签:
13条回答
  • 2020-12-04 21:02

    You can use this function:

    function mapMap(map, fn) {
      return new Map(Array.from(map, ([key, value]) => [key, fn(value, key, map)]));
    }
    

    usage:

    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 }
    */
    
    0 讨论(0)
  • 2020-12-04 21:02

    You can map() arrays, but there is no such operation for Maps. The solution from Dr. Axel Rauschmayer:

    • Convert the map into an array of [key,value] pairs.
    • Map or filter the array.
    • Convert the result back to a map.

    Example:

    let map0 = new Map([
      [1, "a"],
      [2, "b"],
      [3, "c"]
    ]);
    
    const map1 = new Map(
      [...map0]
      .map(([k, v]) => [k * 2, '_' + v])
    );
    

    resulted in

    {2 => '_a', 4 => '_b', 6 => '_c'}
    
    0 讨论(0)
  • 2020-12-04 21:05

    Just use Array.from(iterable, [mapFn]).

    var myMap = new Map([["thing1", 1], ["thing2", 2], ["thing3", 3]]);
    
    var newArr = Array.from(myMap.values(), value => value + 1);
    
    0 讨论(0)
  • 2020-12-04 21:07

    I prefer to extend the map

    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;
      };
    }
    
    0 讨论(0)
  • 2020-12-04 21:10

    You can use myMap.forEach, and in each loop, using map.set to change value.

    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);
    }

    0 讨论(0)
  • 2020-12-04 21:11

    So .map itself only offers one value you care about... That said, there are a few ways of tackling this:

    // 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);
    }
    

    Note, I'm using a lot of new stuff in that second example... ...Array.from takes any iterable (any time you'd use [].slice.call( ), plus Sets and Maps) and turns it into an array... ...Maps, when coerced into an array, turn into an array of arrays, where el[0] === key && el[1] === value; (basically, in the same format that I prefilled my example Map with, above).

    I'm using destructuring of the array in the argument position of the lambda, to assign those array spots to values, before returning an object for each el.

    If you're using Babel, in production, you're going to need to use Babel's browser polyfill (which includes "core-js" and Facebook's "regenerator").
    I'm quite certain it contains Array.from.

    0 讨论(0)
提交回复
热议问题