简体   繁体   English

遍历对象的对象

[英]Loop through an object of objects

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) 我在函数内部使用此对象来检查每次属性之一更改其布尔值的情况: 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. 在此函数内部,我想将它们拆分,以便能够分别检查以abc开头的对象的值。 For that I did: const toCheck = item.id.split("-")[0]; 为此,我做到了: const toCheck = item.id.split("-")[0];

this works fine, it will take only the objects starting with a if that one was clicked. 这可以正常工作,如果单击该对象,它将仅使用以a开头的对象。

the next step is to check if there are both true and false attributes for a specific letter. 下一步是检查特定字母是否同时具有truefalse属性。

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. 因此,我拆分了原始名称以消除(值,项目,其他)值,然后尝试计算true和false属性。 If there are both of them, show a message telling that otherwise, no. 如果两者都存在,请显示一条消息,说明否。

Something is wrong but I don't understand what. 出了点问题,但我不明白。 Any ideas? 有任何想法吗?

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); 

As I know, forEach does not iterate over objects. 据我所知,forEach不会遍历对象。 I suggest you use 我建议你用

const bigObjectKeys = Object.keys(bigObject) const bigObjectKeys = Object.keys(bigObject)

than iterate like this: 比这样迭代:

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

Or use lodash forEach, it can iterate over objects. 或使用lodash forEach,它可以遍历对象。

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

Things you got wrong and to be fixed : 发生错误并要解决的问题:

  1. Iterate through the keys / entries of an object. 遍历对象的keys / entries
  2. Split with - , not with - . -分割,而不用-分割。
  3. Check using if , only after you have completed iterating through all elements. 检查使用if ,您已通过所有元素迭代之后。

 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"); 

Could use Array#filter and Array#every on the Object entries 可以在对象条目上使用Array#filterArray#every

 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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM