Home > Mobile >  every() es6 for nested array is not working?
every() es6 for nested array is not working?

Time:06-08

I expect true for below usage of every but it wasn't, what's wrong with my logic?


const isAllChecked = [
    {
        "id": "1",
        "checked": true,
    },
    {
        "id": "2",
        "checked": true,
        "nested": [
            {
                "id": "2.1",
                "checked": true,
            },
            {
                "id": "2.2",
                "checked": true,
            }
        ]
    },
    {
        "id": "3",
        "checked": true,
    },
].every(
    (o) =>
      o.checked &&
      o.nested?.every((o) => o.checked)
  )

What I wanted: if any of the level 1 checked or nested checked is false then isAllChecked is false, but if non of the checked property in level 1 or nested is false, isAllChecked should return true.

CodePudding user response:

Optional chaining will evaluate to undefined if the chain fails, so for the second iteration

(o) =>
  o.checked &&
  o.nested?.every((o) => o.checked)

will evaluate to

(o) =>
  true
  undefined

You probably wanted

(o) =>
  o.checked &&
  (!o.nested || o.nested.every((o) => o.checked))

or

(o) =>
  o.checked &&
  (o.nested || []).every(o => o.checked)

const isAllChecked = [
    {
        "id": "1",
        "checked": true,
    },
    {
        "id": "2",
        "checked": true,
        "nested": [
            {
                "id": "2.1",
                "checked": true,
            },
            {
                "id": "2.2",
                "checked": true,
            }
        ]
    },
    {
        "id": "3",
        "checked": true,
    },
].every(
    (o) =>
      o.checked &&
      (o.nested || []).every((o) => o.checked)
  )
console.log(isAllChecked);

CodePudding user response:

In the absence of a nested property, o.nested? will evaluate to a falsy value.

You could use a combination of every() and some():

const isAllChecked = [{
    "id": "1",
    "checked": true,
  },
  {
    "id": "2",
    "checked": true,
    "nested": [{
        "id": "2.1",
        "checked": true,
      },
      {
        "id": "2.2",
        "checked": true,
      }
    ]
  },
  {
    "id": "3",
    "checked": true,
  },
].every((o) => o.checked && !o.nested?.some((o) => !o.checked));

console.log(isAllChecked);

CodePudding user response:

If an item doesn't contain the nested property then o.nested?.every((o) => o.checked) will evaluate to false, hence the every method would also return false.

You can instead use Array.prototype.some for the checking the items inside the nested array.

const isAllChecked = [
  { id: "1", checked: true },
  {
    id: "2",
    checked: true,
    nested: [
      { id: "2.1", checked: true },
      { id: "2.2", checked: true },
    ],
  },
  { id: "3", checked: true },
].every((o) => o.checked && !o.nested?.some((o) => !o.checked));

console.log(isAllChecked);

  • Related