62

I want to iterate over all values of a map. I know it's possible to iterate over all keys. But is it possible to iterate directly over the values?

 var map = { key1 : 'value1', key2 : 'value2' }
 for (var key in map) { ...} // iterates over keys
Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129
Matthias M
  • 12,906
  • 17
  • 87
  • 116
  • 3
    The question is so common, that I wonder that no one asked it before. But I can find no question like this on stackoverflow. – Matthias M Nov 26 '15 at 20:33
  • U iterate kvp's. Not just keys, u can access the keys values or both within an iteration. Map[key] would be the value of the iteration – Keith Beard Nov 26 '15 at 20:36
  • @kcbeard - can you support your claim (*U iterate kvp's*) with some proofs / specification? – Amit Nov 26 '15 at 20:37
  • @amit why would u have keys and no access? There may not be a method to directly access them but u can iterate the keys and associated values and do it.therefore u are in actuality iterating both. – Keith Beard Nov 26 '15 at 20:42
  • @kcbeard - That's simply wrong. You're only able to iterate keys, which allow you to access values - if you want to, but you can just as well not access the values at all (for example, if you want to list keys). – Amit Nov 26 '15 at 20:45
  • @amit I'm happy with being wrong but I wouldn't be iterating keys and values, without needing values. Since I see no reason to access a value from outside of its key I see the iteration as the iteration of the pair. Other wise it would not need a dictionary, it would be in array. – Keith Beard Nov 26 '15 at 20:51
  • @amit I'm sure u can objects for a variety of uses. U can have empty values if u want. I'm sure iterating keys are applicable in the right situations. And I can be wrong all the time, but i am glad u can state that. But next time I need to iterate an object be it for need of access to keys or their associated values. It will be done the same way with the same syntax until a proven better way is shown to me. And which case I will be iterating values :) – Keith Beard Nov 26 '15 at 21:09
  • Please rephrase the title to not misslead future readers. – ManuelSchneid3r May 19 '17 at 09:31
  • @ManuelSchneid3r What is you suggestion for a title? – Matthias M May 19 '17 at 09:38
  • "Javascript: Iterate over values of an object". SO is virtually the most general reference for codes. E.g. I came here for a JS Map. – ManuelSchneid3r May 19 '17 at 11:29

8 Answers8

67

It's not a map. It's simply an Object.

Edit: below code is worse than OP's, as Amit pointed out in comments.

You can "iterate over the values" by actually iterating over the keys with:

var value;
Object.keys(map).forEach(function(key) {
    value = map[key];
    console.log(value);
});
André Chalella
  • 13,788
  • 10
  • 54
  • 62
  • 1
    @Matthias it may not seem this way at first, but it makes total sense when you consider one important point: the order of properties in an object is not enforced. e.g. if you say `{a: 1, b: 2, c: 3}` and for loop or go through the `Object.keys`, you're actually not guaranteed to go 1, 2, 3, so a direct looping of values doesn't make as much sense. The `for ... in` (and Object.keys) is closer to a loop that just says "while there are still properties left, get another property". `keys` gives you a place to enforce ordering, e.g. `Object.keys(myobj).sort().forEach(x => console.log(x)` – Josh from Qaribou Nov 26 '15 at 20:47
  • 12
    I don't see how this is any better then OP's `for(var key in map) {map[key]}`. It's longer, less readable, it wastes memory, it's execution is slower - is there any reason at all to do this? – Amit Nov 26 '15 at 21:54
  • I would also provide an actual `Map` usage example. – Eugene Nov 21 '18 at 10:52
25

I iterate like this and it works for me.

for (let [k, v] of myMap) {
    console.log("Key: " + k);
    console.log("Value: " + v);
}

Hope this helps :)

Parag Jadhav
  • 1,853
  • 2
  • 24
  • 41
  • 2
    I create `var myMap = { key1 : 'value1', key2 : 'value2' }`, try use your code and get error: `TypeError: myMap is not iterable`. Only way for me is using `Object.entries(myMap)` as say @dmigo. Maybe you create map in other way? – mkczyk Apr 23 '20 at 16:02
11

In the sense I think you intended, in ES5 or ES2015, no, not without some work on your part.

In ES2016, probably with object.values.

Mind you Arrays in JavaScript are effectively a map from an integer to a value, and the values in JavaScript arrays can be enumerated directly.

['foo', 'bar'].forEach(v => console.log(v)); // foo bar

Also, in ES2015, you can make an object iterable by placing a function on a property with the name of Symbol.iterator:

var obj = { 
    foo: '1', 
    bar: '2',
    bam: '3',
    bat: '4',
};

obj[Symbol.iterator] = iter.bind(null, obj);

function* iter(o) {
    var keys = Object.keys(o);
    for (var i=0; i<keys.length; i++) {
        yield o[keys[i]];
    }
}

for(var v of obj) { console.log(v); } // '1', '2', '3', '4'

Also, per other answers, there are other built-ins that provide the functionality you want, like Map (but not WeakMap because it is not iterable) and Set for example (but these are not present in all browsers yet).

Ben Aston
  • 53,718
  • 65
  • 205
  • 331
7

EcmaScript 2017 introduced Object.entries that allows you to iterate over values and keys. Documentation

var map = { key1 : 'value1', key2 : 'value2' }

for (let [key, value] of Object.entries(map)) {
    console.log(`${key}: ${value}`);
}

The result will be:

key1: value1
key2: value2

dmigo
  • 2,849
  • 4
  • 41
  • 62
1

No, there's no direct method to do that with objects.

The Map type does have a values() method that returns an iterator for the values

Amit
  • 45,440
  • 9
  • 78
  • 110
1

In case you want to deeply iterate into a complex (nested) object for each key & value, you can do so using Object.keys():

const iterate = (obj) => {
    Object.keys(obj).forEach(key => {

    console.log(`key: ${key}, value: ${obj[key]}`)

    if (typeof obj[key] === 'object') {
            iterate(obj[key])
        }
    })
}
Menelaos Kotsollaris
  • 5,776
  • 9
  • 54
  • 68
1

Anyone that comes across this, I managed to solve this in njs ( nginx js ) by doing the following:

>> var map = { key1 : 'value1', key2 : 'value2' }
>> for ( var i in map ){ console.log(i, map[i]) }
key1 value1
key2 value2
0

You could use underscore.js and the each function:

_.each({key1: "value1", key2: "value2"}, function(value) {
  console.log(value);
});
Philipp Claßen
  • 41,306
  • 31
  • 146
  • 239
dpr
  • 10,591
  • 3
  • 41
  • 71