将一种形式的JSON阵列数据转换为另一种形式?

时间:2017-03-16 11:20:10

标签: javascript

我是软件领域的新手。我有一个json数组对象,如

var treeObj = [
      {
        "name": "sriram",
        "refernce_id": "SAN001",
        "sponer_id": "SAN000"
      },
      {
        "name": "neeraja",
        "refernce_id": "SAN002",
        "sponer_id": "SAN001"
      },
      {
        "name": "upender",
        "refernce_id": "SAN003",
        "sponer_id": "SAN001"
      },
      {
        "name": "manoj",
        "refernce_id": "SAN004",
        "sponer_id": "SAN002"
      },
      {
        "name": "shirisha",
        "refernce_id": "SAN005",
        "sponer_id": "SAN002"
      },
      {
        "name": "ragu",
        "refernce_id": "SAN006",
        "sponer_id": "SAN003"
      },
      {
        "name": "santhu",
        "refernce_id": "SAN007",
        "sponer_id": "SAN003"
      }
    ];

这里我将上面的对象传递给一个函数。在该函数中我需要在每个对象中比较引用id和sponer_id,如果它们相等,我们需要将它们推入一个我们称之为子对象的数组,就像下面一样,我们需要在子数组中检查引用id in存在于上面对象的sponer_id中,如果它再次出现,我们需要将它们推送到包含reference_id的对象的子数组中。最终的数组对象看起来像。

[
  {
    "name": "sriram",
    "parent": null,
    "children": [
      {
        "name": "neeraja",
        "parent": "sriram",
        "children": [
          {
            "name": "manoj",
            "parent": "neeraja"
          },
          {
            "name": "shirisha",
            "parent": "neeraja"
          }
        ]
      },
      {
        "name": "upender",
        "parent": "sriram",
        "children": [
          {
            "name": "ragu",
            "parent": "neeraja"
          },
          {
            "name": "santhu",
            "parent": "neeraja"
          }
        ]
      }
    ]
  }
]

这里sriram的treeObj的引用id在neeraja和upender对象中作为sponer id出现。所以neeraja和upender成为sriram的孩子。和neeraja的reference_id在treeObj的manoj和shirisha对象中作为sponer_id出现。同时,子可以有更多的子对象,我们需要动态格式化对象。

我写的功能看起来像

var mainArr = [], subArrs = [], subObj={}, subIds = [], find = "SAN001";
    formatData(treeObj);
    function formatData(treeObj){debugger;
        var arr = [];
        for(var x=0; x<= treeObj.length-1; x++){debugger;
            var sampData = treeObj[x];
            if(find == sampData.sponer_id){
                arr.push(sampData.refernce_id);
                subArrs.push(sampData);
            }
        }
        subIds.push(arr);
        console.log(subIds);
        console.log(subArrs);
        formatData(subArrs);
    }

请指导我哪里出错了。提前谢谢。

2 个答案:

答案 0 :(得分:0)

//1. find all items the have no parent and push them on a stack like so:

let stack = treeObj.reduce((list, item) => {
  if (<ids match>) list.push(item);
  return item;
}, []),

let result = [].concat(stack);

//2. while loop the stack:

while (stack.length > 0) {
  let item = stack.shift();

  item.children = treeObj.reduce((list, child) => {
    if (<ids match>) {
      list.push(child);
    }
    return list;
  }, []).map(child => {
      child.parent = item;
      stack.unshift(item);
      return child;
  });
}

return result;

<强>更新

所以在“好老JS”中有一些改进:

var stack = treeObj.filter(function (item) { 
  return item.<parent_id> === item.<child_id> });

var result = [].concat(stack);

while (stack.length > 0) {
  var item = stack.shift();

  item.children = treeObj.filter(function (child) {
    return item.<id> === child.<parent_id>;
  });

  item.children.forEach(function (child) { stack.unshift(child) });
}

基本上:

  1. 找到根目录并将其保存在堆栈中
  2. while.length > 0

    1. shift()堆栈中的第一项
    2. 找到该项目的所有子项,并在堆栈中unshift
  3. 完成

  4. 可以在循环中完成向项添加父属性或删除不需要的属性。整个事情也可以使用递归来完成,但我曾经通过做这样的事情来运行“太多的递归错误”,所以我更喜欢迭代方法。当然,代替.reduce.filter.forEach,您可以使用常规循环,但我更喜欢功能样式。总而言之,无论你怎么做,都不是那么困难,只需要找到要素,然后再与所有孩子一起重复,等等。使用while循环找到所有子项,或者将该元素作为root用于整个子树。

    祝你好运!

答案 1 :(得分:0)

您基本上是在尝试将数组转换为n-ary树。

将原始树函数输入formatData会为您提供一个数组(arr),其中所有对象的referenceID都是SAN001作为父对象,另一个数组(subArrs)包含所有子节点的sponberId SAN001。

然后将arr存储在subIds,log subIds和subArr中,并继续以递归方式调用subArrs上的格式数据。然后检查subArr哪些对象具有“SAN001作为前驱”(当时应该是所有对象)并在subArr中推送该对象。如果我没有弄错,这会导致无限循环。

改善的起点: 你的“发现”变量没有改变,它是硬连线到“SAN001” - 当你100%确定根对象总是有这个referenceID时,这对你的第一次旅行可能没问题。但是在第二次旅行中,您想要检查哪些对象依赖于第二级元素,因此您需要将find设置为相应的referenceId。

您的subArrs包含取决于SAN001的所有对象。但是在第二次和以后的旅行中,你不希望得到SAN001的孩子,而是subArr中的对象子。因此,您需要遍历在subArr中查找对象子节点的旧对象,而不是遍历寻找SAN001子节点的subArr。

希望清楚一点点。

进一步研究的暗示:你基本上试图用javascript“将数组转换为n-ary树”。