1

There is an object containing objects having this form:

bigObject: {
 "a - values": { atr: true}
 "a - items": { atr: true}
 "a - others": { atr: false}
 "b - values": { atr: true}
 "b - items": { atr: true}
 "b - others": { atr: false}
 "c - values": { atr: false}
 "c - items": { atr: true}
 "c - others": { atr: false}
}

I use this object inside a function to check every time one of the attributes had changed its boolean value: onButtonClicked(item)

it does something like:

onButtonClicked(item) {
 bigObject[item.id].atr= !bigObject[item.id].atr;
}

Inside this function, I want to split them in order to be able to check the values for objects starting with a, b and c separately. For that I did: const toCheck = item.id.split("-")[0];

this works fine, it will take only the objects starting with a if that one was clicked.

the next step is to check if there are both true and false attributes for a specific letter.

For this I tried to do it like:

let countFalse = 0;
let countTrue = 0;
 bigObject.forEach(x => {
 if ((x.split("-")[0]) === toCheck) {
 if (x.atr) {
 countTrue++;
 } else countFalse++;
 }
 if (countTrue && countFalse) {
 console.log("has both true and false attributes");
 } else console.log("nope");
 });

So I'm splitting the original name to get rid of (values, items, others) and after that I try to count the true and false attributes. If there are both of them, show a message telling that otherwise, no.

Something is wrong but I don't understand what. Any ideas?

asked Aug 24, 2018 at 12:37
5
  • where do you get forEach from? Commented Aug 24, 2018 at 12:40
  • @NinaScholz modified it Commented Aug 24, 2018 at 12:43
  • Shouldn't the final if statement be outside the loop. What output are you getting? Commented Aug 24, 2018 at 12:48
  • the error I get is bigObject.forEach is not a function Commented Aug 24, 2018 at 12:50
  • You get that error because forEach is for arrays not object literals Commented Aug 24, 2018 at 13:11

4 Answers 4

1

You could iterate the entries with splitting by ' - ' instead of '-'.

var bigObject = { "a - values": { atr: true }, "a - items": { atr: true }, "a - others": { atr: false }, "b - values": { atr: true }, "b - items": { atr: true }, "b - others": { atr: false }, "c - values": { atr: false }, "c - items": { atr: true }, "c - others": { atr: false } },
 countFalse = 0,
 countTrue = 0,
 toCheck = 'a';
Object.entries(bigObject).forEach(([k, v]) => {
 if (k.split(" - ")[0] !== toCheck) {
 return;
 }
 if (v.atr) {
 countTrue++;
 } else {
 countFalse++;
 }
});
if (countTrue && countFalse) {
 console.log("has both true and false attributes");
} else {
 console.log("nope");
}

A more compact version with an object for counting.

var object = { "a - values": { atr: true }, "a - items": { atr: true }, "a - others": { atr: false }, "b - values": { atr: true }, "b - items": { atr: true }, "b - others": { atr: false }, "c - values": { atr: false }, "c - items": { atr: true }, "c - others": { atr: false } },
 count = { false: 0, true: 0 },
 toCheck = 'a';
Object.entries(object).forEach(([k, { atr }]) => count[atr] += k.startsWith(toCheck));
if (count.true && count.false) {
 console.log("has both true and false attributes");
} else {
 console.log("nope");
}
console.log(count);

answered Aug 24, 2018 at 12:50
Sign up to request clarification or add additional context in comments.

2 Comments

@VigneshRaja, arrow functions are not supported as well, but op is using it, beside let. => ES6
The first version doesn't work for me. countTrue and countFalse are 0 all the time. but the second one is good.
1

As I know, forEach does not iterate over objects. I suggest you use

const bigObjectKeys = Object.keys(bigObject)

than iterate like this:

bigObjectKeys.forEach(element => { bigObject[element] ...})

Or use lodash forEach, it can iterate over objects.

https://lodash.com/docs/4.17.10#forEach

answered Aug 24, 2018 at 12:52

Comments

1

Things you got wrong and to be fixed :

  1. Iterate through the keys/entries of an object.
  2. Split with -, not with -.
  3. Check using if, only after you have completed iterating through all elements.

var countFalse = 0;
var countTrue = 0;
var bigObject= {
 "a - values": { atr: true},
 "a - items": { atr: true},
 "a - others": { atr: false},
 "b - values": { atr: true},
 "b - items": { atr: true},
 "b - others": { atr: false},
 "c - values": { atr: false},
 "c - items": { atr: true},
 "c - others": { atr: false}
}
var toCheck = "a";
 Object.keys(bigObject).forEach(x => {
 if ((x.split(" - ")[0]) === toCheck) {
 if (bigObject[x].atr) {
 countTrue++;
 } else countFalse++;
 }
 });
 
 if (countTrue && countFalse) {
 console.log("has both true and false attributes");
 } else console.log("nope");

To be more efficient,

var countFalse = 0, countTrue = 0;
var bigObject= {
 "a - values": { atr: true},
 "a - items": { atr: false},
 "a - others": { atr: false},
 "b - values": { atr: true},
 "b - items": { atr: true},
 "b - others": { atr: false},
 "c - values": { atr: false},
 "c - items": { atr: true},
 "c - others": { atr: false}
}
var toCheck = "a";
Object.keys(bigObject).forEach(x => {
 if ((x.split(" - ")[0] === toCheck) && !(countTrue>0 && countFalse>0))
 {
 bigObject[x].atr ? countTrue++ : countFalse++;
 }
});
if (countTrue && countFalse) {
 console.log("has both true and false attributes");
 } else console.log("nope");

answered Aug 24, 2018 at 12:53

Comments

1

Could use Array#filter and Array#every on the Object entries

const isMatching = (str) =>{
 const arr = Object.entries(bigObject).filter(e=> e[0].startsWith(str));
 // makes sure every entry has same `atr` as the first entry 
 return arr.every(e => e[1].atr === arr[0][1].atr);
}
['a','b','c'].forEach(s => console.log(s, isMatching(s)))
<script>
const bigObject= {
 "a - values": { atr: true},
 "a - items": { atr: true},
 "a - others": { atr: false},
 "b - values": { atr: true},
 "b - items": { atr: true},
 "b - others": { atr: false},
 "c - values": { atr: false},
 "c - items": { atr: false},
 "c - others": { atr: false}
}
</script>

answered Aug 24, 2018 at 13:02

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.