0

I have an array:

var data = [{
  "name": "Main Hobbies",
  "checked": false,
  "children": [{
    "name": "Dance",
    "checked": false,
    "children": [{
      "name": "Salsa",
      "checked": true
    }, {
      "name": "Solo",
      "checked": false
    }]
  }, {
    "name": "Sports",
    "checked": false,
    "children": [{
      "name": "Cricket",
      "checked": true
    }]
  }]
}, {
  "name": "Game",
  "checked": false,
  "children": [{
    "name": "PUBG",
    "checked": false
  }, {
    "name": "Cricket",
    "checked": false
  }, {
    "name": "Football",
    "checked": true
  }]
}]

function removeFalseElem(arr) {
  arr.forEach(element => {
    if (Array.isArray(element.children) && element.children.length > 0) {
      element.children = element.children.filter(e => {
        return e.checked === true
      });
      element.children.map(e => {
        delete e['id'], delete e['checked']
      })
    } else {
      removeFalseElem(element.children);
    }
    delete element['id'], delete element['checked'];
  });

}
removeFalseElem(data);
console.log(data);

How do I map name to key and children to array contains wherever checked is true. Main hobies should contain Salsa since it is checked. I just want to inverse the approach of this question

output should be like

{
  "Main Hobbies": { Dance: ["Salsa"], Sports: ["Cricket"] },
  Game: ["Football"]
}

have to keep only checked:true values

2 Answers 2

0

You could check if a children contains no children and return an array of names or create an object with the checked nodes.

const
    getObject = array => array.every(({ children }) => !children)
        ? array.reduce((r, { name, checked }) => checked ? [...(r || []), name] : r, undefined)
        : array.reduce((r, { name, checked, children = [] }) => {
            children = getObject(children);
            if (checked || children) r[name] = children;
            return r;
        }, {}),            
    data = [{ name: "Main Hobbies", checked: false, children: [{ name: "Dance", checked: false, children: [{ name: "Salsa", checked: true }, { name: "Solo", checked: false }] }, { name: "Sports", checked: false, children: [{ name: "Cricket", checked: true }] }] }, { name: "Game", checked: false, children: [{ name: "PUBG", checked: false }, { name: "Cricket", checked: false }, { name: "Football", checked: true }] }],
    result = getObject(data);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

Comments

0

With following helper methods, traverse the items and build the required output.
1) filter -- given an array return the name which are true
2) hasGrandChild -- whether the given object has children and children object has children.

const process = data => {
  const filter = arr => arr.filter(x => x.checked).map(x => x.name);
  const hasGrandChild = arr => arr.length > 0 && "children" in arr[0];
  const output = {};

  data.forEach(({ name, children }) => {    
    if (hasGrandChild(children)) {
      const obj = {};
      children.forEach(ch => (obj[ch.name] = filter(ch.children)));
      output[name] = obj;
    } else {
      output[name] = filter(children);
    }
  });
  return output;
};

var data = [
  {
    name: "Main Hobbies",
    checked: false,
    children: [
      {
        name: "Dance",
        checked: false,
        children: [
          {
            name: "Salsa",
            checked: true
          },
          {
            name: "Solo",
            checked: false
          }
        ]
      },
      {
        name: "Sports",
        checked: false,
        children: [
          {
            name: "Cricket",
            checked: true
          }
        ]
      }
    ]
  },
  {
    name: "Game",
    checked: false,
    children: [
      {
        name: "PUBG",
        checked: false
      },
      {
        name: "Cricket",
        checked: false
      },
      {
        name: "Football",
        checked: true
      }
    ]
  }
];

console.log(process(data));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.