How to iterate (keys, values) in JavaScript? [duplicate] - javascript

This question already has answers here:
How do I loop through or enumerate a JavaScript object?
(48 answers)
Closed last year.
I have a dictionary that has the format of
dictionary = {0: {object}, 1:{object}, 2:{object}}
How can I iterate through this dictionary by doing something like
for ((key, value) in dictionary) {
//Do stuff where key would be 0 and value would be the object
}

tl;dr
In ECMAScript 2017, just call Object.entries(yourObj).
In ECMAScript 2015, it is possible with Maps.
In ECMAScript 5, it is not possible.
ECMAScript 2017
ECMAScript 2017 introduced a new Object.entries function. You can use this to iterate the object as you wanted.
'use strict';
const object = {'a': 1, 'b': 2, 'c' : 3};
for (const [key, value] of Object.entries(object)) {
console.log(key, value);
}
Output
a 1
b 2
c 3
ECMAScript 2015
In ECMAScript 2015, there is not Object.entries but you can use Map objects instead and iterate over them with Map.prototype.entries. Quoting the example from that page,
var myMap = new Map();
myMap.set("0", "foo");
myMap.set(1, "bar");
myMap.set({}, "baz");
var mapIter = myMap.entries();
console.log(mapIter.next().value); // ["0", "foo"]
console.log(mapIter.next().value); // [1, "bar"]
console.log(mapIter.next().value); // [Object, "baz"]
Or iterate with for..of, like this
'use strict';
var myMap = new Map();
myMap.set("0", "foo");
myMap.set(1, "bar");
myMap.set({}, "baz");
for (const entry of myMap.entries()) {
console.log(entry);
}
Output
[ '0', 'foo' ]
[ 1, 'bar' ]
[ {}, 'baz' ]
Or
for (const [key, value] of myMap.entries()) {
console.log(key, value);
}
Output
0 foo
1 bar
{} baz
ECMAScript 5:
No, it's not possible with objects.
You should either iterate with for..in, or Object.keys, like this
for (var key in dictionary) {
// check if the property/key is defined in the object itself, not in parent
if (dictionary.hasOwnProperty(key)) {
console.log(key, dictionary[key]);
}
}
Note: The if condition above is necessary only if you want to iterate over the properties which are the dictionary object's very own. Because for..in will iterate through all the inherited enumerable properties.
Or
Object.keys(dictionary).forEach(function(key) {
console.log(key, dictionary[key]);
});

Try this:
dict = {0:{1:'a'}, 1:{2:'b'}, 2:{3:'c'}}
for (var key in dict){
console.log( key, dict[key] );
}
0 Object { 1="a"}
1 Object { 2="b"}
2 Object { 3="c"}

WELCOME TO 2020 *Drools in ES6*
Theres some pretty old answers in here - take advantage of destructuring. In my opinion this is without a doubt the nicest (very readable) way to iterate an object.
const myObject = {
nick: 'cage',
phil: 'murray',
};
Object.entries(myObject).forEach(([k,v]) => {
console.log("The key: ", k)
console.log("The value: ", v)
})
Edit:
As mentioned by Lazerbeak, map allows you to cycle an object and use the key and value to make an array.
const myObject = {
nick: 'cage',
phil: 'murray',
};
const myArray = Object.entries(myObject).map(([k, v]) => {
return `The key '${k}' has a value of '${v}'`;
});
console.log(myArray);
Edit 2:
To explain what is happening in the line of code:
Object.entries(myObject).forEach(([k,v]) => {}
Object.entries() converts our object to an array of arrays:
[["nick", "cage"], ["phil", "murray"]]
Then we use forEach on the outer array:
1st loop: ["nick", "cage"]
2nd loop: ["phil", "murray"]
Then we "destructure" the value (which we know will always be an array) with ([k,v]) so k becomes the first name and v becomes the last name.

The Object.entries() method has been specified in ES2017 (and is supported in all modern browsers):
for (const [ key, value ] of Object.entries(dictionary)) {
// do something with `key` and `value`
}
Explanation:
Object.entries() takes an object like { a: 1, b: 2, c: 3 } and turns it into an array of key-value pairs: [ [ 'a', 1 ], [ 'b', 2 ], [ 'c', 3 ] ].
With for ... of we can loop over the entries of the so created array.
Since we are guaranteed that each of the so iterated array items is itself a two-entry array, we can use destructuring to directly assign variables key and value to its first and second item.

Try this:
var value;
for (var key in dictionary) {
value = dictionary[key];
// your code here...
}

You can do something like this :
dictionary = {'ab': {object}, 'cd':{object}, 'ef':{object}}
var keys = Object.keys(dictionary);
for(var i = 0; i < keys.length;i++){
//keys[i] for key
//dictionary[keys[i]] for the value
}

I think the fast and easy way is
Object.entries(event).forEach(k => {
console.log("properties ... ", k[0], k[1]); });
just check the documentation
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries

using swagger-ui.js
you can do this -
_.forEach({ 'a': 1, 'b': 2 }, function(n, key) {
console.log(n, key);
});

You can use below script.
var obj={1:"a",2:"b",c:"3"};
for (var x=Object.keys(obj),i=0;i<x.length,key=x[i],value=obj[key];i++){
console.log(key,value);
}
outputs
1 a
2 b
c 3

As an improvement to the accepted answer, in order to reduce nesting, you could do this instead, provided that the key is not inherited:
for (var key in dictionary) {
if (!dictionary.hasOwnProperty(key)) {
continue;
}
console.log(key, dictionary[key]);
}
Edit: info about Object.hasOwnProperty here

You can use JavaScript forEach Loop:
myMap.forEach((value, key) => {
console.log('value: ', value);
console.log('key: ', key);
});

Related

how to display both key and value in object using javascript?

I don't know if this is possible in javascript. I have a object that is dynamic.
like
const list = {eb: 'blue', et: 'green'}
anytime my list value will change like
const list = {er: 'yellow', ex: 'black'}
How can get the key value in my object? like I'm going to display both key and value for it.
const ikey = 'eb'
const ivalue = 'blue'
You can use Object.entries.
let list = {eb: 'blue', et: 'green'}
const keyValue = (input) => Object.entries(input).forEach(([key,value]) => {
console.log(key,value)
})
keyValue(list)
list = {er: 'yellow', ex: 'black'}
keyValue(list)
You can use for..in ,
for (var key in list) {
console.log(key, list[key]);
}
With ES6, you can use Object.entries
for (let [key, value] of Object.entries(list)) {
console.log(key, value);
}
try
for(var key in objects) {
var value = objects[key];
}
You can use the Object.keys(objectNameHere) method of the Object prototype to cycle through keys by name and enumeration.
Try this
const list = {er: 'yellow', ex: 'black'};
Object.keys(list).forEach(e=>console.log(e+"="+list[e]))
To avoid much computation and since V8 is great at handling JSON operations, you can simply JSON.stringify(obj) to give you all entries. Only problem is that you will have no control over how certain value types should be handled i.e. in that case, you will only remain with primitives as values.
Use Object.entries() to get a list of key/value pairs from your object. Then you can iterate over the pairs and display them with Array.forEach():
Object.entries({ a: 'hello', b: 3 }).forEach(([key, val]) => {
console.log(key, val);
});
You can get a list of keys with Object.keys() and a list of values with Object.values():
const obj = { a: 'hello', b: 3 };
console.log(Object.keys(obj));
console.log(Object.values(obj));
console.log(Object.entries(obj));
Lastly, you can iterate over the object keys directly with a for...in loop, in which case you have to use bracket notation to access the property on your object:
const obj = { a: 'hello', b: 3 };
for (const key in obj) {
console.log(key, obj[key]);
}
Try using the for..in operator
var obj = {
Name: 'Mohsin ',
Age: 20,
Address: 'Peshawar',
}
for (var keys in obj) {
console.log(keys, ':', obj[keys])
}

ES6 for-of loop in map key value [duplicate]

This question already has answers here:
How do I loop through or enumerate a JavaScript object?
(48 answers)
Closed last year.
I have a dictionary that has the format of
dictionary = {0: {object}, 1:{object}, 2:{object}}
How can I iterate through this dictionary by doing something like
for ((key, value) in dictionary) {
//Do stuff where key would be 0 and value would be the object
}
tl;dr
In ECMAScript 2017, just call Object.entries(yourObj).
In ECMAScript 2015, it is possible with Maps.
In ECMAScript 5, it is not possible.
ECMAScript 2017
ECMAScript 2017 introduced a new Object.entries function. You can use this to iterate the object as you wanted.
'use strict';
const object = {'a': 1, 'b': 2, 'c' : 3};
for (const [key, value] of Object.entries(object)) {
console.log(key, value);
}
Output
a 1
b 2
c 3
ECMAScript 2015
In ECMAScript 2015, there is not Object.entries but you can use Map objects instead and iterate over them with Map.prototype.entries. Quoting the example from that page,
var myMap = new Map();
myMap.set("0", "foo");
myMap.set(1, "bar");
myMap.set({}, "baz");
var mapIter = myMap.entries();
console.log(mapIter.next().value); // ["0", "foo"]
console.log(mapIter.next().value); // [1, "bar"]
console.log(mapIter.next().value); // [Object, "baz"]
Or iterate with for..of, like this
'use strict';
var myMap = new Map();
myMap.set("0", "foo");
myMap.set(1, "bar");
myMap.set({}, "baz");
for (const entry of myMap.entries()) {
console.log(entry);
}
Output
[ '0', 'foo' ]
[ 1, 'bar' ]
[ {}, 'baz' ]
Or
for (const [key, value] of myMap.entries()) {
console.log(key, value);
}
Output
0 foo
1 bar
{} baz
ECMAScript 5:
No, it's not possible with objects.
You should either iterate with for..in, or Object.keys, like this
for (var key in dictionary) {
// check if the property/key is defined in the object itself, not in parent
if (dictionary.hasOwnProperty(key)) {
console.log(key, dictionary[key]);
}
}
Note: The if condition above is necessary only if you want to iterate over the properties which are the dictionary object's very own. Because for..in will iterate through all the inherited enumerable properties.
Or
Object.keys(dictionary).forEach(function(key) {
console.log(key, dictionary[key]);
});
Try this:
dict = {0:{1:'a'}, 1:{2:'b'}, 2:{3:'c'}}
for (var key in dict){
console.log( key, dict[key] );
}
0 Object { 1="a"}
1 Object { 2="b"}
2 Object { 3="c"}
WELCOME TO 2020 *Drools in ES6*
Theres some pretty old answers in here - take advantage of destructuring. In my opinion this is without a doubt the nicest (very readable) way to iterate an object.
const myObject = {
nick: 'cage',
phil: 'murray',
};
Object.entries(myObject).forEach(([k,v]) => {
console.log("The key: ", k)
console.log("The value: ", v)
})
Edit:
As mentioned by Lazerbeak, map allows you to cycle an object and use the key and value to make an array.
const myObject = {
nick: 'cage',
phil: 'murray',
};
const myArray = Object.entries(myObject).map(([k, v]) => {
return `The key '${k}' has a value of '${v}'`;
});
console.log(myArray);
Edit 2:
To explain what is happening in the line of code:
Object.entries(myObject).forEach(([k,v]) => {}
Object.entries() converts our object to an array of arrays:
[["nick", "cage"], ["phil", "murray"]]
Then we use forEach on the outer array:
1st loop: ["nick", "cage"]
2nd loop: ["phil", "murray"]
Then we "destructure" the value (which we know will always be an array) with ([k,v]) so k becomes the first name and v becomes the last name.
The Object.entries() method has been specified in ES2017 (and is supported in all modern browsers):
for (const [ key, value ] of Object.entries(dictionary)) {
// do something with `key` and `value`
}
Explanation:
Object.entries() takes an object like { a: 1, b: 2, c: 3 } and turns it into an array of key-value pairs: [ [ 'a', 1 ], [ 'b', 2 ], [ 'c', 3 ] ].
With for ... of we can loop over the entries of the so created array.
Since we are guaranteed that each of the so iterated array items is itself a two-entry array, we can use destructuring to directly assign variables key and value to its first and second item.
Try this:
var value;
for (var key in dictionary) {
value = dictionary[key];
// your code here...
}
You can do something like this :
dictionary = {'ab': {object}, 'cd':{object}, 'ef':{object}}
var keys = Object.keys(dictionary);
for(var i = 0; i < keys.length;i++){
//keys[i] for key
//dictionary[keys[i]] for the value
}
I think the fast and easy way is
Object.entries(event).forEach(k => {
console.log("properties ... ", k[0], k[1]); });
just check the documentation
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries
using swagger-ui.js
you can do this -
_.forEach({ 'a': 1, 'b': 2 }, function(n, key) {
console.log(n, key);
});
You can use below script.
var obj={1:"a",2:"b",c:"3"};
for (var x=Object.keys(obj),i=0;i<x.length,key=x[i],value=obj[key];i++){
console.log(key,value);
}
outputs
1 a
2 b
c 3
As an improvement to the accepted answer, in order to reduce nesting, you could do this instead, provided that the key is not inherited:
for (var key in dictionary) {
if (!dictionary.hasOwnProperty(key)) {
continue;
}
console.log(key, dictionary[key]);
}
Edit: info about Object.hasOwnProperty here
You can use JavaScript forEach Loop:
myMap.forEach((value, key) => {
console.log('value: ', value);
console.log('key: ', key);
});

Using Objects in For Of Loops

Why isn't is possible to use objects in for of loops? Or is this a browser bug? This code doesn't work in Chrome 42, saying undefined is not a function:
test = { first: "one"}
for(var item of test) {
console.log(item)
}
The for..of loop only supports iterable objects like arrays, not objects.
To iterate over the values of an object, use:
for (var key in test) {
var item = test[key];
}
You can use this syntax:
const myObject = {
first: "one",
second: "two",
};
for (const [key, value] of Object.entries(myObject)) {
console.log(key, value); // first one, second two
}
However, Object.entries has poor support right now does not work in IE or iOS Safari. You'll probably might need a polyfill. See https://caniuse.com/mdn-javascript_builtins_object_entries for the latest scoop.
See also Object.keys to iterate just the keys, or Object.values for just the values.
If you are storing data in a key-value store, please use Map which is explicitly designed for this purpose.
If you have to use an object though, ES2017 (ES8) allows you to use Object.values:
const foo = { a: 'foo', z: 'bar', m: 'baz' };
for (let value of Object.values(foo)) {
console.log(value);
}
If that isn't supported yet, use a polyfill: Alternative version for Object.values()
And finally if you're supporting an older environment that don't support this syntax, you'll have to resort to using forEach and Object.keys:
var obj = { a: 'foo', z: 'bar', m: 'baz' };
Object.keys(obj).forEach(function (prop) {
var value = obj[prop];
console.log(value);
});
Iterator, Iterable and for..of loop in ECMAScript 2015/ ES6
let tempArray = [1,2,3,4,5];
for(element of tempArray) {
console.log(element);
}
// 1
// 2
// 3
// 4
// 5
But if we do
let tempObj = {a:1, b:2, c:3};
for(element of tempObj) {
console.log(element);
}
// error
We get error because for..of loop works only on Iterables, that is, the object which has an ##iterator that adheres to Iterator protocol, meaning it must have an object with a next method. The next method takes no arguments and it should return an object with these two properties.
done: signals that the sequence has ended when true, and false means there may be more values
value: this is the current item in the sequence
So, to make an object Iterable that is to make it work with for..of we can:
1 .Make an object an Iterable by assigning to it’s mystical ##iterator property through the Symbol.iterator property.Here is how:
let tempObj = {a:1, b:2, c:3};
tempObj[Symbol.iterator]= () => ({
next: function next () {
return {
done: Object.keys(this).length === 0,
value: Object.keys(this).shift()
}
}
})
for(key in tempObj){
console.log(key)
}
// a
// b
// c
2.Use Object.entries, which returns an Iterable:
let tempObj = {a:1, b:2, c:3};
for(let [key, value] of Object.entries(tempObj)) {
console.log(key, value);
}
// a 1
// b 2
// c 3
3.Use Object.keys, here is how:
let tempObj = {a:1, b:2, c:3};
for (let key of Object.keys(tempObj)) {
console.log(key);
}
// a
// b
// c
Hope this helps!!!!!!
I made objects iterable with this code:
Object.prototype[Symbol.iterator] = function*() {
for(let key of Object.keys(this)) {
yield([ key, this[key] ])
} }
Usage:
for(let [ key, value ] of {}) { }
Alternativly:
for(let [ key, value ] of Object.entries({})) { }
Because object literal does not have the Symbol.iterator property. To be specific, you can only iterate over String, Array, Map, Set, arguments, NodeList(not widely support) and Generator with for...of loop.
To deal with Object Literal iteration, you have two options.
for...in
for(let key in obj){
console.log(obj[key]);
}
Object.keys + forEach
Object.keys(obj).forEach(function(key){
console.log(obj[key]);
});
The answer is No. It's not possible to use For..Of with Object literals.
I agree with Overv that For..Of is only for iterables.
I had exactly the same question because I use Objects to iterate over keys and values with for..in. But I just realized that that's what ES6 MAPS and SETS are for.
let test = new Map();
test.set('first', "one");
test.set('second', "two");
for(var item of test) {
console.log(item); // "one" "two"
}
Hence it achieves the goal of not having to use for..In (validating with hasOwnProperty) and not having to use Object.keys().
Additionally, your keys aren't limited to strings. You can use numbers, objects, or other literals.
Object literals don't have built-in iterators, which are required to work with for...of loops. However, if you don't want to go thru the trouble of adding your own [Symbol.iterator] to your object, you can simply use the Object.keys() method. This method returns an Array object, which already has a built-in iterator, so you can use it with a for...of loop like this:
const myObject = {
country: "Canada",
province: "Quebec",
city: "Montreal"
}
for (let i of Object.keys(myObject)) {
console.log("Key:", i, "| Value:", myObject[i]);
}
//Key: country | Value: Canada
//Key: province | Value: Quebec
//Key: city | Value: Montreal
It is possible to define an iterator over any giving object, this way you can put different logic for each object
var x = { a: 1, b: 2, c: 3 }
x[Symbol.iterator] = function* (){
yield 1;
yield 'foo';
yield 'last'
}
Then just directly iterate x
for (let i in x){
console.log(i);
}
//1
//foo
//last
It is possible to do the same thing on the Object.prototype object And have a general iterator for all objects
Object.prototype[Symbol.iterator] = function*() {
for(let key of Object.keys(this)) {
yield key
}
}
then iterate your object like this
var t = {a :'foo', b : 'bar'}
for(let i of t){
console.log(t[i]);
}
Or this way
var it = t[Symbol.iterator](), p;
while(p = it.next().value){
console.log(t[p])
}
I just did the following to easily console out my stuff.
for (let key in obj) {
if(obj.hasOwnProperty(key){
console.log(`${key}: ${obj[key]}`);
}
}
Using Array Destruction you can iterate it as follows using forEach
const obj = { a: 5, b: 7, c: 9 };
Object.entries(obj).forEach(([key, value]) => {
console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
});
How about using Object.keys to get an array of keys? And then forEach on the Array?
obj = { a: 1, b:2}
Object.keys(obj).forEach( key => console.log(`${key} => ${obj[key]}`))
One-Line answer based on Mozilla doc Generator - Symbol iterator - Add this to your object to make it iterable:
*[Symbol.iterator]() { yield* Object.values(this) }
example 1 - getting values:
const person = {
name: "SeyyedKhandon",
age: 31,
*[Symbol.iterator]() { yield* Object.values(this) }
}
// Now you can use "for of"
for (let value of person) {
console.log(value);
}
// and also you "spread it"
console.log([...person])
example 2 - getting key-values using *[Symbol.iterator]() { yield* Object.entries(this) }:
const person = {
name: "SeyyedKhandon",
age: 31,
*[Symbol.iterator]() { yield* Object.entries(this) }
}
// for of
for (let item of person) {
console.log("key:",item[0]," -> ", "value:",item[1]);
}
// spread it
console.log([...person])
Also you can add it later:
person[Symbol.iterator]= function*() { yield* Object.entries(person) }
const person = {
name: "SeyyedKhandon",
age: 31,
}
person[Symbol.iterator]= function*() { yield* Object.entries(person) }
// for of
for (let item of person) {
console.log("key:",item[0]," -> ", "value:",item[1]);
}
// spread it
console.log([...person])
What about using
function* entries(obj) {
for (let key of Object.keys(obj)) {
yield [key, obj[key]];
}
}
for ([key, value] of entries({a: "1", b: "2"})) {
console.log(key + " " + value);
}
in ES6 you could go with generator:
var obj = {1: 'a', 2: 'b'};
function* entries(obj) {
for (let key of Object.keys(obj)) {
yield [key, obj[key]];
}
}
let generator = entries(obj);
let step1 = generator.next();
let step2 = generator.next();
let step3 = generator.next();
console.log(JSON.stringify(step1)); // {"value":["1","a"],"done":false}
console.log(JSON.stringify(step2)); // {"value":["2","b"],"done":false}
console.log(JSON.stringify(step3)); // {"done":true}
Here is the jsfiddle.
In the output you will get an object with the "value" and "done" keys. "Value" contains everything you want it to have and "done" is current state of the iteration in bool.
This is from 2015, we are in 2022 and I think we can say that a good way to solve this is adding an iterator.
For example if we had a snippet like this:
const obj = { a: 1, b: 2, c: 3 }
const [first] = obj
It will give us an error that object is not iterable
However, it can be iterated using for ... in
const obj = { a: 1, b: 2, c: 3 }
for (const key in obj) {
console.log('key: ', key)
}
Teo, how we can make our obj instance iterable?
Well it is easy just add the iterable protocol like this:
const obj = { a: 'one', b: 'two', c: 'three' }
obj[Symbol.iterator] = () => {
const entries = Object.entries(obj)
return {
next() {
return {
done: entries.length === 0,
value: entries.shift(),
}
},
}
}
const [first] = obj
const [k, v] = first
console.log(`first: [k: ${k}, v:${v}]`)
// Now we can use for of
for (const [k, v] of obj) {
console.log(`[k:${k}, v:${v}]`)
}
This is a very basic implementation you can replace Object.entries(obj) with Object.keys(obj) or Object.values(obj) according to the needs of the project.

Iterate over Object Literal Values

I have a standard jQuery plugin set up that creates default settings at the top:
jQuery.fn.myPlugin = function(options) {
var defaults = {
starts: "0px,0px",
speed: 250, ...
};
o = $.extend(defaults, options);
}
I have another variable called numberOfObjects.
I'm trying to loop through the default variables. For each object found (from numberOfObjects) I need to duplicate the value of the variable value. So, if the numberOfObjects variable is 3, the defaults.starts should be 0px,0px > 0px,0px > 0px,0px. The & gt; is used to split values.
This is what I currently have. X represents the variable name inside defaults. Y represents the variable for the current value of x. I've gotten this far and have no clue what to do next.
for (x in defaults) { // x is defaults.x
defaults.x = defaults.x + " > y";
}
var obj = {
'foo': 1,
'bar': 2
};
for (var key in obj) {
console.log(obj[key]);
}
Or with jQuery:
$.each(obj, function(key, value) {
console.log(this, value, obj[key]);
});
You should not have to depend on jQuery for this.
Object.keys(obj).forEach(function (key) {
var value = obj[key];
// do something with key or value
});
Mozilla Developer documentation - https://developer.mozilla.org
Polyfill for old browsers
View Performance Results - https://jsperf.com
Let's setup our basic object before we get started:
const x = {
x: 1,
y: 2,
z: 3
};
We can use Object.keys(x) to return an array of all of the keys within our object.
Object.keys(x)
> ['x', 'y', 'z']
Now we able to map, filter, reduce and loop over our array and do something with that value within our object:
Object.keys(x).map(key => x[key] + 1)
> [2,3,4]
Object.keys(x).forEach(key => console.log(x[key]))
> [1,2,3]
The main take away here is that we have to use the key to access that specific value, it works but it feels a little clunky. ES2017 brings with it Object.values() which can be used as a nice shortcut for returning an array of all of the values within an Object.
Object.values(x)
> [1,2,3]
Object.values(x).map(value => value + 1)
> [2,3,4]
Object.values(x).forEach(value => console.log(value))
> [1,2,3]
You can read more about Object.values() at MDN, they also include a polyfill, should you need to support older browsers & browsers which haven't yet implemented it.
There's also Object.entries() which conveniently allows you to access the keys and the values. It returns an array containing arrays (first item being the key and the second item being the value.
Object.entries(x);
> [['x', 1], ['y', 2], ['z', 3]]
We can use de-structuring to easily get at these values:
Object.entries(x).map(([key, value]) => console.log(key, value))
To iterate over an object's values you can use a for...of loop with Object.values.
const myObj = {a: 1, b: 2}
for (let value of Object.values(myObj)) {
console.log(`value=${value}`)
}
// output:
// value=1
// value=2
If you want the key and value when iterating, you can use Object.entries.
const myObj = {a: 1, b: 2}
for (let [key, value] of Object.entries(myObj)) {
console.log(`key=${key} value=${value}`)
}
// output:
// key=a value=1
// key=b value=2
Best practice is to validate if the object attribute that is being iterated over is from the object itself and not inherited from the prototype chain. You can check this using .hasOwnProperty(): (Of course if you do want to include inherited properties just remove the if statement).
Here is the general case:
for(var index in object) {
if (object.hasOwnProperty(index)) {
var value = object[index];
// do something with object value here.
}
}
Here is the example case you mentioned where you want to create a duplicate object with the value of each key duplicated replicated according to the value of the var numberofobjects (i've added in two solutions whereby you either modify the existing object or create a new one):
// function to repeat value as a string inspired by disfated's answer here http://stackoverflow.com/questions/202605/repeat-string-javascript
function repeatValue(value, count) {
value = String(value); // change to string to be able to add " > " as in question
if (count < 1) return '';
var result = '';
while (count > 1) {
if (count & 1) result += value + " > ";
count >>= 1, value += " > " + value;
}
return result + value;
}
var numberofobjects = 3;
var newObject = {}; // for use if creating a duplicate object with the new values
for(var x in defaults) {
if (defaults.hasOwnProperty(x)) {
//use this to replace existing values
defaults[x] = repeatValue(defaults[x], numberofobjects);
//or use this to create values in the new object
newObject[x] = repeatValue(defaults[x], numberofobjects);
}
}
In your code:
for(x in defaults){
defaults.x = defaults.x + " > y";
}
You need to say defaults[x] instead of defaults.x.
x is a variable holding a string that is the key into the defaults object, and the bracket (array-style) syntax lets you use that variable to get the property. With the dot notation defaults.x is looking for a property actually called "x", the equivalent of defaults["x"].
var yourVariable = {
Bobe: 23,
Pope: 33,
Doop: 43,
Dope: 53
};
for(var keyName in yourVariable){
document.write(keyName, " : ",yourVariable[keyName]," ");
};
Taken from Mozilla:
const object1 = {
a: 'somestring',
b: 42,
c: false
};
console.log(Object.values(object1));
// expected output: Array ["somestring", 42, false]

Get array of object's keys

I would like to get the keys of a JavaScript object as an array, either in jQuery or pure JavaScript.
Is there a less verbose way than this?
var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [];
for (var key in foo) {
keys.push(key);
}
Use Object.keys:
var foo = {
'alpha': 'puffin',
'beta': 'beagle'
};
var keys = Object.keys(foo);
console.log(keys) // ['alpha', 'beta']
// (or maybe some other order, keys are unordered).
This is an ES5 feature. This means it works in all modern browsers but will not work in legacy browsers.
The ES5-shim has a implementation of Object.keys you can steal
You can use jQuery's $.map.
var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' },
keys = $.map(foo, function(v, i){
return i;
});
Of course, Object.keys() is the best way to get an Object's keys. If it's not available in your environment, it can be trivially shimmed using code such as in your example (except you'd need to take into account your loop will iterate over all properties up the prototype chain, unlike Object.keys()'s behaviour).
However, your example code...
var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [];
for (var key in foo) {
keys.push(key);
}
jsFiddle.
...could be modified. You can do the assignment right in the variable part.
var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [], i = 0;
for (keys[i++] in foo) {}
jsFiddle.
Of course, this behaviour is different to what Object.keys() actually does (jsFiddle). You could simply use the shim on the MDN documentation.
In case you're here looking for something to list the keys of an n-depth nested object as a flat array:
const getObjectKeys = (obj, prefix = '') => {
return Object.entries(obj).reduce((collector, [key, val]) => {
const newKeys = [ ...collector, prefix ? `${prefix}.${key}` : key ]
if (Object.prototype.toString.call(val) === '[object Object]') {
const newPrefix = prefix ? `${prefix}.${key}` : key
const otherKeys = getObjectKeys(val, newPrefix)
return [ ...newKeys, ...otherKeys ]
}
return newKeys
}, [])
}
console.log(getObjectKeys({a: 1, b: 2, c: { d: 3, e: { f: 4 }}}))
I don't know about less verbose but I was inspired to coerce the following onto one line by the one-liner request, don't know how Pythonic it is though ;)
var keys = (function(o){var ks=[]; for(var k in o) ks.push(k); return ks})(foo);
Summary
For getting all of the keys of an Object you can use Object.keys(). Object.keys() takes an object as an argument and returns an array of all the keys.
Example:
const object = {
a: 'string1',
b: 42,
c: 34
};
const keys = Object.keys(object)
console.log(keys);
console.log(keys.length) // we can easily access the total amount of properties the object has
In the above example we store an array of keys in the keys const. We then can easily access the amount of properties on the object by checking the length of the keys array.
Getting the values with: Object.values()
The complementary function of Object.keys() is Object.values(). This function takes an object as an argument and returns an array of values. For example:
const object = {
a: 'random',
b: 22,
c: true
};
console.log(Object.values(object));
Year 2022 and JavaScript still does not have a sound way to work with hashes?
This issues a warning but works:
Object.prototype.keys = function() { return Object.keys(this) }
console.log("Keys of an object: ", { a:1, b:2 }.keys() )
// Keys of an object: Array [ "a", "b" ]
// WARN: Line 8:1: Object prototype is read only, properties should not be added no-extend-native
That said, Extending Built-in Objects is Controversial.
If you decide to use Underscore.js you better do
var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [];
_.each( foo, function( val, key ) {
keys.push(key);
});
console.log(keys);

Categories

Resources