根据某些属性过滤嵌套数组

时间:2020-04-23 21:43:26

标签: javascript arrays ecmascript-6

我有一个数组:

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

我如何将name映射到key并将children映射到array包含checkedtrue的位置。 Main hobies应包含Salsa,因为已选中。我只想颠倒这种question

的方法

输出应类似于

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

必须仅保留checked:true个值

2 个答案:

答案 0 :(得分:0)

您可以检查子代是否不包含任何子代,并返回名称数组或使用选中的节点创建对象。

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

答案 1 :(得分:0)

使用以下辅助方法,遍历各项并构建所需的输出。
1)过滤器-给定数组返回名称为true
2)hasGrandChild-给定对象是否有子对象,而子对象是否有子对象。

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