32
var map = {};
map[key] = value;

How can I

  • assign value 1 if key does not yet exist in the object
  • increment the value by 1 if it exists

Could I do better than:

if (map[key] == null) map[key] = 0;
map[key] = map[key]++;
membersound
  • 81,582
  • 193
  • 585
  • 1,120
  • 2
    Try if (typeof map [key] === "undefined") to check for inexistence. Normally something that doesnt exist in your map will be undefined. Not null. – Theodoros Klikas Sep 20 '16 at 09:52
  • Can't you just use `hasOwnProperty` to check for the existence of the prop you are looking for ? – DavidDomain Sep 20 '16 at 10:10
  • 6
    Possible duplicate of [Javascript Object increment item if not exist](https://stackoverflow.com/questions/18690814/javascript-object-increment-item-if-not-exist) – holroy Apr 13 '19 at 16:52

9 Answers9

54

Here you go minimize your code.

map[key] = (map[key]+1) || 1 ;
ricky
  • 1,644
  • 1
  • 13
  • 25
  • 2
    By "flag hoisting" you mean "short-circuit evaluation". This doesn't have anything to do with hoisting, although "flag hoisting" is an amusing conflation. – JJJ Sep 20 '16 at 09:58
  • 1
    without having flag hoisting property in JavaScript. You can not use so called "short-circuit evaluation". Ultimately, Its utilizing the same concept. – ricky Sep 20 '16 at 10:00
  • you can call it variable hoisting . – ricky Sep 20 '16 at 10:03
  • 2
    There is no kind of hoisting involved in your code at all. – JJJ Sep 20 '16 at 10:04
  • check the first answer : http://stackoverflow.com/questions/8597501/which-design-patterns-take-advantage-of-javascripts-hoisting-behavior – ricky Sep 20 '16 at 10:06
  • 1
    You're misreading that question. `var a = a || 1;` would involve hoisting because of the `var` keyword (the local variable is hoisted). Here you're manipulating a property of an existing object, therefore there's nothing that would get hoisted anywhere. – JJJ Sep 20 '16 at 10:08
  • this is how hoisting works : map[key] = (map[key]+1) || 1 ; it will break down in two statement var map[key] = undefined; / map[key] = (undefined+1) || 1; // outuput =1 if no variable hoisitng then this will give syntax error saying map[key] is not defined – ricky Sep 20 '16 at 10:18
  • 1
    @ricky: nope. Getting a value by non-existing key returns `undefined` (without any invisible assignment). `undefined + 1` gives NaN, which is a falsey value, so the control goes to `|| 1` part. I assure you nothing is being hoisted here. Go read up on the term. – Sergio Tulentsev Sep 20 '16 at 10:23
  • @ricky: also multiline code is impossible to read in comments. Looks much better as a link to gist or pastebin or whatever. That way you can have syntax highlighting too :) – Sergio Tulentsev Sep 20 '16 at 10:28
  • @Sergio: I agree with your explanation. In this case i am wrong if the variable would have direct object then my concept will apply. – ricky Sep 20 '16 at 10:30
  • @ricky: "error saying map[key] is not defined". `map` IS defined. And `map[key]` is not an identifier. – Sergio Tulentsev Sep 20 '16 at 10:31
  • 1
    Breaks when existing value is -1. Then map[key]+1 is 0 which is falsy so overall result of the increment is 1 rather than 0. – Fruitbat Aug 14 '20 at 09:24
  • Better: `map[key] = (map[key] || 0) + 1` as in [How to increment an object property value if it exists, else set the initial value?](https://stackoverflow.com/a/18690820/1157324) – Fruitbat Aug 14 '20 at 16:27
18

Recently it could be

map[key] = (map[key] ?? 0) + 1;

Nullish coalescing operator

kawauso
  • 355
  • 2
  • 5
6

You can check if the object doesn't have the specific key and set it or increase existing key value by one:

function assignKey(obj, key) {
  typeof obj[key] === 'undefined' ? obj[key] = 1 : obj[key]++;
}

var map = {};

assignKey(map, 2);
assignKey(map, 2);
assignKey(map, 4);
assignKey(map, 1);
assignKey(map, 2);
assignKey(map, 5);
assignKey(map, 1);
console.log(map);
Alex Char
  • 32,879
  • 9
  • 49
  • 70
5

ES6 provides a dedicated class for maps, Map. You can easily extend it to construct a "map with a default value":

class DefaultMap extends Map {

    constructor(defVal, iterable=[]) {
        super(iterable);
        this.defVal = defVal;
    }

    get(key) {
        if(!this.has(key))
            this.set(key, this.defVal);
        return super.get(key);
    }
}

m = new DefaultMap(9);
console.log(m.get('foo'));
m.set('foo', m.get('foo') + 1);
console.log(m.get('foo'))

(Ab)using Objects as Maps had several disadvantages and requires some caution.

georg
  • 211,518
  • 52
  • 313
  • 390
  • The code snippet has an error; `Uncaught SecurityError`. I'm not sure if this is a problem with the code itself or with some StackOverflow issue. Just thought I'd point it out. – Taylor R Nov 06 '18 at 19:14
3

you can use ternory operator like this

 map[key] ? map[key]++ : map[key] = 1;
Blaze
  • 31
  • 3
1

It would be better if you convert array's value into integer and increment it. It will be robust code. By default array's value is string. so in case you do not convert it to integer then it might not work cross browser.

if (map[key] == null) map[key] = 0;
map[key] = parseInt(map[key])+1;
nirmal
  • 2,143
  • 1
  • 19
  • 29
0
function addToMap(map, key, value) {
    if (map.has(key)) {       
        map.set(key, parseInt(map.get(key), 10) + parseInt(value, 10));
    } else {
        map.set(key, parseInt(value, 10));
    }       
}
0

Creating an object:

    tagObject = {};
    tagObject['contentID'] = [];  // adding an entry to the above tagObject
    tagObject['contentTypes'] = []; // same explanation as above
    tagObject['html'] = [];

Now below is the occurrences entry which I am addding to the above tag Object..

ES 2015 standards: function () {} is same as () => {}

          let found = Object.keys(tagObject).find(
                (element) => {
                    return element === matchWithYourValueHere;
                });

          tagObject['occurrences'] = found ? tagObject['occurrences'] + 1 : 1;

this will increase the count of a particular object key..

ggorantala
  • 196
  • 2
  • 16
0

The shortest code would be:

map[key] = ++map[key] || 1

Nick
  • 95
  • 8