遍历对象的对象

时间:2018-08-24 12:37:57

标签: javascript loops for-loop foreach iterator

有一个包含以下形式对象的对象:

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}
}

我在函数内部使用此对象检查每次属性之一更改其布尔值:onButtonClicked(item)

它的作用类似于:

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

在此函数内,我想将它们拆分以便能够分别检查以abc开头的对象的值。为此,我做了:const toCheck = item.id.split("-")[0];

这可以正常工作,如果单击该对象,它将仅使用以a开头的对象。

下一步是检查特定字母的truefalse属性。

为此,我尝试这样做:

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

因此,我将原始名称拆分以消除(值,项目和其他),然后尝试计算true和false属性。如果它们都存在,请显示一条消息,否则,不会。

出了点问题,但我不明白。有什么想法吗?

4 个答案:

答案 0 :(得分:1)

您可以用' - '而不是'-'来拆分条目。

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

一种更紧凑的版本,带有一个用于计数的对象。

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

答案 1 :(得分:1)

据我所知,forEach不会遍历对象。我建议您使用

const bigObjectKeys = Object.keys(bigObject)

比这样迭代:

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

或者使用lodash forEach,它可以遍历对象。

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

答案 2 :(得分:1)

您出错并要解决的问题:

  1. 遍历对象的keys / entries
  2. -而不是-分开。
  3. 只有在完成所有元素的迭代之后,才使用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");

要提高效率,

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

答案 3 :(得分:1)

可以在对象条目上使用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>