Как обработать дерево JSON? - PullRequest
2 голосов
/ 12 июня 2019

У меня есть дерево вроде:

{
  "nodes": [
    {
      "id":1,
      "children":[
        {
          "id":3,
          "children":[
            {"id":4, "children":[]},
            {"id":5, "children":[{"id":6, "children":[]}]}
          ]
        },
        {"id":2, "children":[]}
      ]
    }
  ]
}

Как разобрать это дерево, чтобы поместить каждую node внутри children в один новый массив? Я думаю, мне нужно проанализировать это рекурсивно. Можете ли вы помочь, пожалуйста?

Вывод должен быть таким:

let array = [
  {"id":1},
  {"id":2},
  {"id":3},
  {"id":4},
  {"id":5},
  {"id":6},
]

Ответы [ 8 ]

3 голосов
/ 12 июня 2019

Вы можете использовать итеративный и рекурсивный подход. Если вы хотите получить заказанный результат, вы можете добавить сортировку.

function getValues(array) {
    return array.reduce((r, { id, children }) => [...r, { id }, ...getValues(children)], []);
}

var data = { nodes: [{ id: 1, children: [{ id: 3, children: [{ id: 4, children: [] }, { id: 5, children: [{ id: 6, children: [] }] }] }, { id: 2, children: [] }] }] };

console.log(getValues(data.nodes));
.as-console-wrapper { max-height: 100% !important; top: 0; }
1 голос
/ 12 июня 2019

Есть много способов сделать это, один из них - мое решение.Я уверен, вы найдете лучший путь - но я нашел Object.entries технику довольно легко.

const myObj = {
  "nodes": [
    {
      "id":1,
      "children":[
        {
          "id":3,
          "children":[
            {"id":4, "children":[]},
            {"id":5, "children":[{"id":6, "children":[]}]}
          ]
        },
        {"id":2, "children":[]}
      ]
    }
  ]
}

let noteArray = Object.entries(myObj.nodes);
let pushArray = [];

for(const [noteKey, noteValue] of noteArray) {
  pushArray.push({"id": noteValue.id});
  
  for(const [childKey, childValue] of Object.entries(noteValue.children)) {
    pushArray.push({"id": childValue.id});
    
    for(const [child2Key, child2Value] of Object.entries(childValue.children)) {
      pushArray.push({"id": child2Value.id});
    }
  }
}

console.log(pushArray);
1 голос
/ 12 июня 2019

Вы можете использовать рекурсивную функцию, как показано ниже:

var nodeObject = {
  "nodes": [{
    "id": 1,
    "children": [{
        "id": 3,
        "children": [{
            "id": 4,
            "children": []
          },
          {
            "id": 5,
            "children": [{
              "id": 6,
              "children": []
            }]
          }
        ]
      },
      {
        "id": 2,
        "children": []
      }
    ]
  }]
}

var ids = [];

function getIds(node) {
  ids.push({
    id: node.id
  });
  if (node.children && node.children.length > 0) {
    node.children.forEach(childNode => getIds(childNode))
  }
}
nodeObject.nodes.forEach(node => getIds(node))
console.log(ids);
1 голос
/ 12 июня 2019

Вы можете создать свою собственную функцию синтаксического анализа, используя метод reduce, чтобы вернуть все дочерние узлы в структуре плоского массива.

const tree = {"nodes":[{"id":1,"children":[{"id":3,"children":[{"id":4,"children":[]},{"id":5,"children":[{"id":6,"children":[]}]}]},{"id":2,"children":[]}]}]}

function parse(arr) {
  return arr.reduce((r, e) => {
    const {children, ...rest} = e;
    r.push(rest)

    const childNodes = parse(children);
    if (childNodes.length) r.push(...childNodes);

    return r;
  }, [])
}

const data = parse(tree.nodes);
console.log(data)
0 голосов
/ 12 июня 2019

Обычная рекурсия:

data = {
  "nodes": [
    {
      "id":1,
      "children":[
        {
          "id":3,
          "children":[
            {"id":4, "children":[]},
            {"id":5, "children":[{"id":6, "children":[]}]}
          ]
        },
        {"id":2, "children":[]}
      ]
    }
  ]
}


var ids = [];

function getIdsFromArray(children) {

     children.forEach((item) => {
     
        if (item.id)
           ids.push({"id": item.id});
           
           
        if (item.children && Array.isArray(item.children)) 
          getIdsFromArray(item.children)
     
     })
}


getIdsFromArray(data.nodes);

console.log(ids)
 //# sourceURL=snippet:///test
0 голосов
/ 12 июня 2019

Основным рекурсивным решением будет:

var tree = {
  "nodes": [
    {
      "id":1,
      "children":[
        {
          "id":3,
          "children":[
            {"id":4, "children":[]},
            {"id":5, "children":[{"id":6, "children":[]}]}
          ]
        },
        {"id":2, "children":[]}
      ]
    }
  ]
}

function parse(tree, current) {
    if (current === undefined || current === null) {
        current = [];
    }
    if (Array.isArray(tree)) {
        tree.forEach(function (node) {
            if (node.id !== undefined) {
              current = current.concat([{ id: node.id }]);
            }
            if (node.children !== undefined) {
               current = parse(node.children, current);
             }
        });
    }
   
    return current;
}      

console.log(parse(tree.nodes));
0 голосов
/ 12 июня 2019

Вы можете использовать функцию для итерации объекта по свойству, как показано ниже

var object = {
  "nodes": [
    {
      "id":1,
      "children":[
        {
          "id":3,
          "children":[
            {"id":4, "children":[]},
            {"id":5, "children":[{"id":6, "children":[]}]}
          ]
        },
        {"id":2, "children":[]}
      ]
    }
  ]
}

var result = [];
function iterate(obj, stack) {
        
        for (var property in obj) {
            if (obj.hasOwnProperty(property)) {
                if (typeof obj[property] == "object") {
                    iterate(obj[property], stack + '.' + property);
                } else {
                    //console.log(property + "   " + obj[property]);
                    result.push({[property]: obj[property]});
                    //$('#output').append($("<div/>").text(stack + '.' + property))
                }
            }
        }
        
    }
    
iterate(object, 'id');
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="output"></div>
0 голосов
/ 12 июня 2019

Рекурсивное решение - путь:

const data = {"nodes":[{"id":1,"children":[{"id":3,"children":[{"id":4,"children":[]},{"id":5,"children":[{"id":6,"children":[]}]}]},{"id":2,"children":[]}]}]};

const getChildren = obj => {
  let result = [];
  obj.children.forEach(child => {
    if (child.children && child.children.length) {
      result.push({ id: child.id });
      result = result.concat(getChildren(child));
    } else {
      result.push({ id: child.id });
    }
  });
  return result;
};

let res = data.nodes.flatMap(getChildren);

console.log(res);
snip-css
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...