【问题标题】:Flat JSON unflatten to hierarchy with multiple parents as String平面 JSON 展开为具有多个父级的层次结构作为字符串
【发布时间】:2020-03-08 04:46:52
【问题描述】:

我正在尝试展开一些 json 数据。如果我使用我的测试数据,就像跟踪一切正常!

var data = [
  { "title": 1, "parentids": [0] }, 
  { "title": 2, "parentids": [1] },
  { "title": 3, "parentids": [1] },
  { "title": 4, "parentids": [2, 3] },
];

因此,如果我对这个数据集使用我的函数,我会收到以下结构,这实际上就是我想要的。

[
 {
  "title": 0,
  "parentids": [],
  "children": [
   {
    "title": 1,
    "parentids": [
     0
    ],
    "children": [
     {
      "title": 2,
      "parentids": [
       1
      ],
      "children": [
       {
        "title": 4,
        "parentids": [
         2,
         3
        ],
        "children": []
       }
      ]
     },
     {
      "title": 3,
      "parentids": [
       1
      ],
      "children": [
       {
        "title": 4,
        "parentids": [
         2,
         3
        ],
        "children": []
       }
      ]
     }
    ]
   }
  ]
 }
]

但是!我的数据发生了变化。不幸的是,我的头衔和父代现在是字符串值

var data = [
  { "title": "any", "parentids": [""] },
  { "title": "culture", "parentids": ["any"] },
  { "title": "building", "parentids": ["any"] },
  { "title": "museum", "parentids": ["culture", "building"] },
];

我确实尝试了很多来更改和编辑我现有的代码,但它不起作用......要么没有输出,要么层次结构不像预期的那样。这是我的实际函数,适用于第一个数据集。我怎么能改变它,它适用于字符串 parentid;

function unflatten(arr) {
  var node,
    graph = [], 
    mapped = [];

  // First map the nodes of the array to an object
  for (var i = 0, len = arr.length; i < len; i++) {
    node = arr[i];
    mapped[node.title] = node;
    mapped[node.title]['children'] = [];
  }

  // 2. assign children:
  mapped.forEach(function (node) {  
     // Add as child to each of the parents 
    node.parentids.forEach(function (parentid) {
      if (mapped[parentid]) {
        mapped[parentid]['children'].push(node);
      } else {
        // If parent does not exist as node, create it at the root level,
        // and add it to first level elements array.
        graph.push(mapped[parentid] = {
          title: parentid,   //name in this case its 0
          parentids: [],
          children: [node]

        });
      }
    });
  });
  return graph;

};

var graph = unflatten(types);

console.log(JSON.stringify(graph, null, 4));
document.body.innerHTML = "<pre>" + (JSON.stringify(graph, null, " "))

我不确定,但我认为带有“if (mapped[parentid]”) 的第二部分会导致问题?因为我现在使用的是字符串而不是整数?我真的不知道如何继续...我很感激任何一种提示或解决方案! 提前致谢,祝您度过愉快的一天/一周

【问题讨论】:

  • 您的方法是错误的,因为当 parentids 数组为空时,这意味着对象必须位于根级别。如果没有任何条件地做了 foreach 事情,请检查 parentids 的长度。否则将该元素添加到根目录。
  • @Eldar 在您的提示下,我能够自己管理它。谢谢!

标签: javascript arrays json list graph


【解决方案1】:

你可以使用这个解决方案:

var data = [
  { "title": "any", "parentids": [] },
  { "title": "culture", "parentids": ["any"] },
  { "title": "building", "parentids": ["any"] },
  { "title": "museum", "parentids": ["culture", "building"] },
]

// For each object in data, assign a children property.
data.forEach(o => o.children = [])

// For each object in data, assign a key/object pair using the title e.g
// { 
//   culture: { "title": "culture", "parentids": ["any"] }} 
//   ... 
// }
const map = data.reduce((a, o) => (a[o.title] = o, a), {})

// For each object in data, and for each parentid in that object,
// push this object to the object where the given parentid === ID
data.forEach(o => o.parentids.forEach(id => map[id] && map[id].children.push(o)))

// Filter the data object to only root elements (where there are no parentids)
const output = data.filter(e => !e.parentids.length)

console.log(output);

【讨论】:

  • 嘿,科比,谢谢它有效!我现在会使用它,因为时间在流逝,即使到目前为止我还没有 100% 理解它......非常感谢
  • @Mikesh 你不明白什么?我会尽力解释发生了什么?
  • 我很高兴它起作用了,我没有深入研究它。在我找到自己的解决方案后(我还在学习,所以我不只是想使用你的代码)我看了看,是的,我猜你的代码比我的好得多,所以我会使用它。谢谢=)
  • 我的意思是你想让我解释我的代码吗?还是您已经了解它的工作原理? @Mikesh
  • 如果你能解释一下代码,我想这会对我有很大帮助!谢谢
【解决方案2】:

这是我最终得到的代码

var types1 = [
  { "title": "any", "parentids": [] },
  { "title": "culture", "parentids": ["any"] },
  { "title": "building", "parentids": ["any"] },
  { "title": "museum", "parentids": ["culture", "building"] },
];


function unflatten(arr) {
  var node,
    graph = [], 
    mapped = {};

  // First map the nodes of the array to an object -> create a hash table.
  for (var i = 0, len = arr.length; i < len; i++) {
    node = arr[i];

    mapped[node.title] = node;
    mapped[node.title]['children'] = [];
  }

  // 2. assign children:
  for (var index in mapped) {  
    if (mapped[index].parentids.length) {
      mapped[index].parentids.forEach(function (parentid) {
        mapped[parentid]['children'].push(mapped[index]);
      });
    } else {
      graph.push(mapped[index] = {
        title: mapped[index].parentids, 
        parentids: [],
        children: [mapped[index]]

      });
    }

  };
  return graph;

};

var graph = unflatten(types1);

console.log(JSON.stringify(graph, null, 4));
document.body.innerHTML = "<pre>" + (JSON.stringify(graph, null, " "))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-16
    • 1970-01-01
    相关资源
    最近更新 更多