JavaScript - Map() increment value

前端 未结 5 1450
说谎
说谎 2021-01-07 18:53

I have a map as follows:

let map = new Map();
map.set(\"a\", 1);
//Map is now {\'a\' => 1}

I want to change the value of a

相关标签:
5条回答
  • 2021-01-07 19:27

    According to the ECMAScript® 2015 Language Specification states, Map manipulation is based prototypes and the prototype methods assigned to add or retrieve data to or from a Map are the set and get methods respectively.

    Except for the unnecessary parenthesis around your map.get("a"), your code is perfectly okay. That's how the Map is meant to be used. If you are looking for something that "may" reduce the length of your code and if it does works for your specific requirement, you may use the JavaScript Object.

    So dear, your code is just the same as this:

    map.set("a", map.get("a")+1);
    
    0 讨论(0)
  • 2021-01-07 19:30

    Map does not have a built-in feature that increments a value. However, since JavaScript constructs can be modified you can actually do that yourself:

    let map = new Map()
    // Modify your map
    map.constructor.prototype.increment = function (key) {
      this.has(key) && this.set(key, this.get(key) + 1)
    }
    map.constructor.prototype.decrement = function (key) {
      this.has(key) && this.set(key, this.get(key) - 1)
    }
    
    // Now you can use it right away
    map.set('test', 1)
    map.increment('test')
    map.increment('test')
    map.decrement('test')
    console.log(map.get('test')) // returns 2
    

    To make this easier in the future, you can abstract it into a utility:

    class CyborgMap extends Map {
      constructor() {
        super()
        
        this.constructor.prototype.increment = function (key) {
          this.has(key) && this.set(key, this.get(key) + 1)
        }
        this.constructor.prototype.decrement = function (key) {
          this.has(key) && this.set(key, this.get(key) - 1)
        }
      }
    }
    

    Now import it and use it:

    import { CyborgMap } from "./utils"
    
    let map = new CyborgMap()
    map.set('test', 1)
    map.increment('test')
    map.increment('test')
    map.decrement('test')
    console.log(map.get('test')) // returns 2
    
    0 讨论(0)
  • 2021-01-07 19:32

    I don't know any cleaner way to do that, nevertheless I think that everything depends from the context of your code.

    If you are iterating an array or something else and you want to increase your variable, I suggest to use a local variable to do that and, at the end of the iteration, set the value in the map.

    var i = map.get('a')
    
    values.forEach( el => {
      i += el.someField
    })
    
    map.set('a', i)
    
    0 讨论(0)
  • 2021-01-07 19:36

    Map#get returns the value of the specified element. It is opposite of an object accessor (object['a']) and is not eligible for a left-hand side assignment.

    The conclusion is to use always Map#set for setting a new value.

    0 讨论(0)
  • 2021-01-07 19:38

    The way you do it is fine. That is how you need to do it if you are working with primitive values. If you want to avoid the call to map.set, then you must revert to a reference to a value. In other words, then you need to store an object, not a primitive:

    let map = new Map();
    map.set("a", {val: 1});
    

    And then incrementing becomes:

    map.get("a").val++;
    
    0 讨论(0)
提交回复
热议问题