Цикл через объект объектов - PullRequest
0 голосов
/ 24 августа 2018

Существует объект, содержащий объекты, имеющие такую ​​форму:

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

Внутри этой функции я хочу разделить их, чтобы иметь возможность проверять значения для объектов, начиная с a, b и c по отдельности. Для этого я сделал: const toCheck = item.id.split("-")[0];

это работает нормально, он будет принимать только те объекты, которые начинаются с, если по нему щелкнули.

следующий шаг - проверить, есть ли атрибуты true и false для конкретной буквы.

Для этого я попытался сделать это так:

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 голосов
/ 24 августа 2018

Можно использовать Array#filter и Array#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>
0 голосов
/ 24 августа 2018

Как я знаю, forEach не перебирает объекты. Я предлагаю вам использовать

const bigObjectKeys = Object.keys (bigObject)

чем повторять, как это:

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

Или используйте lodash forEach, он может перебирать объекты.

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

0 голосов
/ 24 августа 2018

Вещи, которые вы ошиблись и должны быть исправлены:

  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");
0 голосов
/ 24 августа 2018

Вы можете повторять записи с разделением на ' - ' вместо '-'.

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