this code below works well but the ESLint plugin show the warning:"Using 'ForinStatement' is not allowed" so i want to change it to other ways to prevent the warning message:
let count = 0;
for (const key in groups) {
if (Object.prototype.toString.call(groups[key]) === '[object Object]') {
if ({}.hasOwnProperty.call(groups[key], 'users')) {
count += groups[key].users.length;
}
}
}
this code below works well but the ESLint plugin show the warning:"Using 'ForinStatement' is not allowed" so i want to change it to other ways to prevent the warning message:
let count = 0;
for (const key in groups) {
if (Object.prototype.toString.call(groups[key]) === '[object Object]') {
if ({}.hasOwnProperty.call(groups[key], 'users')) {
count += groups[key].users.length;
}
}
}
Share
Improve this question
edited Nov 1, 2016 at 9:34
methis
asked Nov 1, 2016 at 9:24
methismethis
4711 gold badge6 silver badges16 bronze badges
13
|
Show 8 more comments
4 Answers
Reset to default 15If your goal alone is to avoid errors in your ESLint, i'd suggest using Object.keys(obj).forEach()
I usually go with this approach in my own projects.
Pseudo-example:
Object.keys(groups).forEach(key => {
if (Object.prototype.toString.call(groups[key]) === '[object Object]') {
if ({}.hasOwnProperty.call(groups[key], 'users')) {
count += groups[key].users.length;
}
}
});
Here are three possible ways of solving this depending on what part of the map you need, the keys, the values or both the key/value pairs.
If you need not only the key, but the value in the map you might choose:
for (const [key, value] of Object.entries(object)) {
// ...
}
If you only need the keys:
for (const key of Object.keys(object)) {
// ...
}
Finally, if you only need the values, but not the keys you can use:
for (const value of Object.values(object)) {
// ...
}
I like to implement an it
helper function to iterate objects:
function* it(obj) {
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
yield [key, obj[key]];
}
}
}
Then you can iterate like so:
for (const [key, value] of it(obj)) {
if ({}.toString.call(value) === '[object Object]' &&
value.hasOwnProperty('users')) {
count += connections[key].users.length;
}
}
While this method still uses for..in
, it's now contained in one function, and you can make a single exception in your ESLint file for it. Then you don't need to use it ever again.
You use a single line for checking and counting.
let count = Object.keys(groups).reduce((r, key) =>
r + (('users' in groups[key]) && groups[key].users.length || 0), 0);
const key
? Why notlet
orvar
. Also{}.hasOwnProperty.call(groups[key], 'users')
can begroups[key].hasOwnProperty( 'users')
– Rajesh Commented Nov 1, 2016 at 9:27key
doesn't change inside of the body of the loop. That's the recommended practice. – Madara's Ghost Commented Nov 1, 2016 at 9:27Object.keys(groups).forEach
not work? – evolutionxbox Commented Nov 1, 2016 at 9:29for..in
:Object.values
,Object.entries
orObject.keys
withfor..of
orforEach
orreduce
. The real question is do you understand whyfor..in
is semantically different than those options and do you needfor..in
for your logic to function correctly? – CodingIntrigue Commented Nov 1, 2016 at 10:06