1

I have one array of nested objects. I want to edit each of them and add property "status" and value of this property can be "selected", "unselected" or "indent".

1. status: 'selected'

  • his lvlScope array is not empty
  • lvlScope array of all his children is not empty

2. status: 'unselected'

  • his lvlScope array is empty
  • lvlScope array of all his children is empty

3. status: 'indent'

  • his lvlScope array is empty and at least one of his children has lvlScope array that is not empty
  • his lvlScope array is not empty and at least one of his children has lvlScope array that is empty
  • his lvlScope array is not empty and all his children have lvlScope array that are empty

all children means all nested children

Does anyone has idea how to do that?

let data = [{
    id: 1,
    name: 'level1',
    lvlScope: [1, 2, 3],
    lvl1Subs: []
  },
  {
    id: 2,
    name: 'level1',
    lvlScope: [],
    lvl1Subs: [{
        id: 1,
        name: 'level2',
        lvlScope: [],
        lvl2Subs: [{
            id: 1,
            name: 'level3',
            lvlScope: [],
            lvl3Subs: []
          },
          {
            id: 2,
            name: 'level3',
            lvlScope: [1, 2],
            lvl3Subs: []
          },
          {
            id: 3,
            name: 'level3',
            lvlScope: [1],
            lvl3Subs: [{
                id: 1,
                name: 'level4',
                lvlScope: [],
                lvl4Subs: [{
                    id: 1,
                    name: 'level5',
                    lvlScope: []
                  },
                  {
                    id: 2,
                    name: 'level5',
                    lvlScope: [1]
                  }
                ]
              },
              {
                id: 2,
                name: 'level4',
                lvlScope: [],
                lvl4Subs: []
              }
            ]
          }
        ]
      },
      {
        id: 2,
        name: 'level2',
        lvlScope: [1],
        lvl2Subs: []
      }
    ]
  },
  {
    id: 3,
    name: 'level1',
    lvlScope: [],
    lvl1Subs: [{
        id: 1,
        name: 'level2',
        lvlScope: [1, 2],
        lvl2Subs: []
      },
      {
        id: 2,
        name: 'level2',
        lvlScope: [],
        lvl2Subs: []
      },
      {
        id: 3,
        name: 'level2',
        lvlScope: [1, 2, 3],
        lvl2Subs: [{
          id: 1,
          name: 'level3',
          lvlScope: [],
          lvl3Subs: []
        }]
      },
      {
        id: 4,
        name: 'level2',
        lvlScope: [],
        lvl2Subs: []
      },
      {
        id: 5,
        name: 'level2',
        lvlScope: [1, 2],
        lvl2Subs: []
      }
    ]
  }
]

const levels = (data) => {

  data.map((lvl1) => {
    console.log('-lvl1', lvl1)
    lvl1.lvl1Subs.map((lvl2) => {
      console.log('--lvl2', lvl2)
      lvl2.lvl2Subs.map((lvl3) => {
        console.log('---lvl3', lvl3)
        lvl3.lvl3Subs.map((lvl4) => {
          console.log('----lvl4', lvl4)
          lvl4.lvl4Subs.map((lvl5) => {
            console.log('-----lvl5', lvl5)
          })
        })
      })
    })
  })
}

console.log(levels(data))
kasp3rsky
  • 127
  • 1
  • 3
  • 15
  • Can you ellaborate on what you have been doing to achive your intended result? You already have some code for displaying/printing your different levels that you can start from. Additionally, you might want to look into recursion to solve some of these. – abondoa Dec 17 '21 at 12:00

2 Answers2

1

You didn't say anything about what to assign when the level has no children. Furthermore is not clear if the check should be done only to direct childs or also in the nested child. Here is a solution considering that no child means selected or unselected and considering the check only to direct childs.

const addStatus = (data, level = 1) => {
  const scope = emptyScope(data);
  let childrenScopes = [];
  for (let child of data["lvl" + level + "Subs"]
    ? data["lvl" + level + "Subs"]
    : []) {
    childrenScopes.push(emptyScope(child));
    addStatus(child, level + 1);
  }

  let status = "indent";
  let found = childrenScopes.find((c) => c === !scope);
  if (found === true || found === false) {
    found = true;
  } else {
    found = false;
  }
  if ((!found || !childrenScopes.length) && !scope) {
    status = "selected";
  }
  if ((!found || !childrenScopes.length) && scope) {
    status = "unselected";
  }

  data["status"] = status;
};

const emptyScope = (data) => {
  if (data.lvlScope.length > 0) {
    return false;
  }
  return true;
};

data.map((d) => addStatus(d, 1));

console.log(data);

Edit after information was provided in comment

const addStatus = (data, level = 1) => {
  const scope = emptyScope(data);
  let childrenScopes = childScopes(data, level, []);

  let status = "indent";
  let found = typeof childrenScopes.find((c) => c === !scope) === "boolean";

  if ((!found || !childrenScopes.length) && !scope) {
    status = "selected";
  }
  if ((!found || !childrenScopes.length) && scope) {
    status = "unselected";
  }

  data["status"] = status;

  for (let child of data["lvl" + level + "Subs"]
    ? data["lvl" + level + "Subs"]
    : []) {
    addStatus(child, level + 1);
  }
};

const childScopes = (data, level, scopes) => {
  for (let child of data["lvl" + level + "Subs"]
    ? data["lvl" + level + "Subs"]
    : []) {
    scopes.push(emptyScope(child));
    childScopes(data["lvl" + level + "Subs"], level, scopes);
  }
  return scopes;
};

const emptyScope = (data) => {
  if (data.lvlScope.length > 0) {
    return false;
  }
  return true;
};

data.map((d) => addStatus(d, 1));

console.log(data);
Nicola Scionti
  • 380
  • 1
  • 12
  • If level has no children it depends only of itself. If lvlScope is empty then should be 'unselected', if lvlScope is not empty then should be 'selected'. Check should be done also in the nested child. – kasp3rsky Dec 17 '21 at 13:57
  • try to check the edit please – Nicola Scionti Dec 17 '21 at 15:28
0

you can easily solve this problem think in the way of a recursive function.

abhishek sahu
  • 648
  • 4
  • 8