带子对象的Javascript递归JSON数组

时间:2019-05-09 10:54:31

标签: javascript json recursion

有没有一种方法可以递归以下JSON,而不会循环嵌套的子级?

我的递归函数必须缺少一个大小写,因为它没有返回所有内容。

iterateTree(node, children) {
    console.log(node.name)

    if(node.children.length == 0) {
      return;
    }

    for(var i = 0; i < children.length; i++) {
      var child_node = children[i];

      return this.iterateTree(child_node, child_node.children);
    }
  }

for(var i = 0; i < sample.length; i++) {
      var node = sample[i];
      this.iterateTree(node, node.children);
    }

var sample = [
  {
    "name": "hello world",
    "children": [
      {
        "name": "fruits",
        "children": []
      },
      {
        "name": "vegetables",
        "children": []
      },
      {
        "name": "meats",
        "children": [
          {
            "name": "pork",
            "children": []
          },
          {
            "name": "beef",
            "children": []
          },
          {
            "name": "chicken",
            "children": [
              {
                "name": "organic",
                "children": []
              },
              {
                "name": "farm raised",
                "children": []
              }
            ]
          },
        ]
      }
    ]
  },
  {
    "name": "second folder",
    "children": []
  },
  {
    "name": "third folder",
    "children": [
      {
        "name": "breads",
        "children": []
      },
      {
        "name": "coffee",
        "children": [
          {
            "name": "latte",
            "children": []
          },
          {
            "name": "cappucino",
            "children": []
          },
          {
            "name": "mocha",
            "children": []
          },
        ]
      },
    ]
  }
]

旨在实现以下输出(类似于文件结构)

hello world
-fruits
-vegetables
-meats 
--pork
--beef
--chicken
---organic
---farm raised
second folder
third folder
-breads
-coffee
--latte
--cappucino
--mocha

3 个答案:

答案 0 :(得分:3)

您可以使用reduce方法创建递归函数,以遍历嵌套数据结构,返回数组,然后对该数组使用join方法。

var sample = [{"name":"hello world","children":[{"name":"fruits","children":[]},{"name":"vegetables","children":[]},{"name":"meats","children":[{"name":"pork","children":[]},{"name":"beef","children":[]},{"name":"chicken","children":[{"name":"organic","children":[]},{"name":"farm raised","children":[]}]}]}]},{"name":"second folder","children":[]},{"name":"third folder","children":[{"name":"breads","children":[]},{"name":"coffee","children":[{"name":"latte","children":[]},{"name":"cappucino","children":[]},{"name":"mocha","children":[]}]}]}]

function tree(data, prev = '') {
  return data.reduce((r, e) => {
    r.push(prev + e.name)
    if (e.children.length) r.push(...tree(e.children, prev + '-'));
    return r;
  }, [])
}

const result = tree(sample).join('\n')
console.log(result)

要在HTML中创建相同的结构,可以改用forEach方法。

var sample = [{"name":"hello world","children":[{"name":"fruits","children":[]},{"name":"vegetables","children":[]},{"name":"meats","children":[{"name":"pork","children":[]},{"name":"beef","children":[]},{"name":"chicken","children":[{"name":"organic","children":[]},{"name":"farm raised","children":[]}]}]}]},{"name":"second folder","children":[]},{"name":"third folder","children":[{"name":"breads","children":[]},{"name":"coffee","children":[{"name":"latte","children":[]},{"name":"cappucino","children":[]},{"name":"mocha","children":[]}]}]}]

function tree(data, parent) {
  const ul = document.createElement('ul');
  data.forEach(el => {
    const li = document.createElement('li');
    li.textContent = el.name;
    ul.appendChild(li);
    if (el.children.length) {
      tree(el.children, li)
    }
  })
  parent.appendChild(ul)
}

const parent = document.getElementById('root')
tree(sample, parent)
<div id="root"></div>

答案 1 :(得分:0)

var sample = [{"name":"hello world","children":[{"name":"fruits","children":[]},{"name":"vegetables","children":[]},{"name":"meats","children":[{"name":"pork","children":[]},{"name":"beef","children":[]},{"name":"chicken","children":[{"name":"organic","children":[]},{"name":"farm raised","children":[]}]}]}]},{"name":"second folder","children":[]},{"name":"third folder","children":[{"name":"breads","children":[]},{"name":"coffee","children":[{"name":"latte","children":[]},{"name":"cappucino","children":[]},{"name":"mocha","children":[]}]}]}]

  level = 0;
  var hyphens = '';

  function recursive_loop(s) {  
    console.log(hyphens + s.name);
    var c = s.children;
    if (c.length) hyphens += '-';
    var empty = false;
    for (let i = 0; i < c.length; i++) {
      if (c[i].children) {
        recursive_loop(c[i]);
      }
      if (c[i].children.length)
        empty = true;
    }
    if (empty) hyphens = '';
  }
  for (let i = 0; i < sample.length; i++) {
    recursive_loop(sample[i]);
  }

答案 2 :(得分:0)

我们现在使用object-scan进行所有数据处理/遍历。一旦将头缠绕在它上,它就会非常强大。这是解决问题的方法

const objectScan = require('object-scan');

const display = (input) => objectScan(['**'], {
  rtn: 'entry',
  filterFn: ({ value }) => typeof value === 'string'
})(input)
  .reverse()
  .map(([k, v]) => `${'-'.repeat(k.length / 2 - 1)}${v}`);

const sample = [{"name":"hello world","children":[{"name":"fruits","children":[]},{"name":"vegetables","children":[]},{"name":"meats","children":[{"name":"pork","children":[]},{"name":"beef","children":[]},{"name":"chicken","children":[{"name":"organic","children":[]},{"name":"farm raised","children":[]}]}]}]},{"name":"second folder","children":[]},{"name":"third folder","children":[{"name":"breads","children":[]},{"name":"coffee","children":[{"name":"latte","children":[]},{"name":"cappucino","children":[]},{"name":"mocha","children":[]}]}]}];

const result = display(sample);
result.forEach((l) => console.log(l));
/* =>
hello world
-fruits
-vegetables
-meats
--pork
--beef
--chicken
---organic
---farm raised
second folder
third folder
-breads
-coffee
--latte
--cappucino
--mocha
 */