javascript - 将子组中的名称排序为组 - 重组 json 数据

标签 javascript d3.js lodash

我正在尝试重组我的 JSON 数据以将其传递给 D3.js 以创建 TreeMap 。下面的链接有虚拟数据。原始数据包括不同的水果/蔬菜名称,具有一些属性,例如这种水果的组(例如 {name: apple, group1: tree fruit}),但我想将水果名称结构化为子组和子组到顶级组(例如水果>树果>苹果)。您会在最后几行中找到正确的结构作为评论。

我目前的问题是组名称重复了很多次,我找不到一种方法来一次获取组 3 名称(可能还有 4 和 5)以将其推送到新的数据结构。您会在第 145 行发现逻辑错误,但我也会在这篇文章中复制我尝试获取 group3 名称的尝试。

项目:https://codepen.io/phng/pen/JpGEVg?editors=0010

if (group3) {
  var checkGroup3 = function(recentName) {
    for (var j = 0; j < materialData.children.length; j++) {
      for (var k = 0; k < materialData.children[j].children.length; k++) {
        console.log(_.find(materialData.children[j].children[k].children, {
          'name': recentName
        }));
        if (!_.find(materialData.children[j].children[k].children, {
            'name': recentName
          })) {
          //console.log(recentName);
        }
      }
    }
  }
  checkGroup3(); // this function was a try to get the group3 names once, failed
  if (i != 0) {
    if (group.name != data.children[i - 1].gruppe_3) { // error here. Condition checks the group 3 aka "gruppe_3" multiple times because in first round the group name isn't in the JSON, then another group name follows, is also not in JSON but then the first one comes again and the group name isn't again like the grupp_3 name and get pushed to the JSON again.
      materialData.children[aboveGroupPosition].children[aboveGroupPositionThirdLayer].children.push(group)
    }
  } else if (i === 0) {
    materialData.children[aboveGroupPosition].children[aboveGroupPositionThirdLayer]

      .children.push(group)
  }
}

原始数据:

var data = {
'name': 'Big Data',
'children': [
    {
        'name': 'Apple',
        'gruppe_1': 'Fruits',
        'gruppe_2': 'Red Fruits',
        'gruppe_3': 'Tree Fruits',
        'gruppe_4': 'Winter Favourite Fruits',
        'gruppe_5': 'Candy Fruits'
    },
    {
        'name': 'Pomegranate',
        'gruppe_1': 'Fruits',
        'gruppe_2': 'Red Fruits',
        'gruppe_3': 'Tree Fruits',
        'gruppe_4': 'Winter Favourite Fruits',
        'gruppe_5': 'Candy Fruits'
    },
    {
        'name': 'Pear',
        'gruppe_1': 'Fruits',
        'gruppe_2': 'Green Fruits',
        'gruppe_3': 'Medium Tree Fruits'
    },
    {
        'name': 'Strawberry',
        'gruppe_1': 'Nuts',
        'gruppe_2': 'Red Nuts',
        'gruppe_3': 'Awkward Nuts'
    },
    {
        'name': 'Hazelnuts',
        'gruppe_1': 'Nuts',
        'gruppe_2': 'Brown Nuts',
        'gruppe_3': 'Normal Nuts'
    },
    {
        'name': 'Cucumber',
        'gruppe_1': 'Vegetable',
        'gruppe_2': 'Green Vegetable',
        'gruppe_3': 'Long Vegetable'
    },
    {
        'name': 'Maracuya'
    },
    {
        'name': 'Green Kiwi',
        'gruppe_1': 'Fruits',
        'gruppe_2': 'Green Fruits'
    },
    {
        'name': 'Cherry',
        'gruppe_1': 'Fruits',
        'gruppe_2': 'Red Fruits',
        'gruppe_3': 'Tree Fruits'
    },
]

我尝试得到的结构:

{
  "name":"Big Data",
  "children":[
    {
      "name":"Fruits",
      "children":[
        "Maracuya",
        {
          "name":"Red Fruits",
          "parent":"Fruits",
          "children":[
            {
              "name":"Tree Fruits",
              "children":[
                "Cherry",
                {
                  "name":"Winter Favourite Fruits",
                  "children":[
                    {
                      "name":"Candy Fruits",
                      "children":[
                        "Apple",
                        "Pomegranate"
                      ]
                    }
                  ]
                }
              ]
            }
          ]
        },
        {
          "name":"Green Fruits",
          "children":[
            "Green Kiwi",
            {
              "name":"Medium Tree Fruits",
              "children":[
                "Pear"
              ]
            }
          ]
        }
      ]
    },
    {
      "name":"Vegetable",
      "children":[
        {
          "name":"Green Vegetable",
          "children":[
            {
              "name":"Long Vegetable",
              "children":[
                "Cucumber"
              ]
            }
          ]
        }
      ]
    },
    {
      "name":"Nuts",
      "children":[
        {
          "name":"Red Nuts",
          "children":[
            {
              "name":"Awkward Nuts",
              "children":[
                "Strawberry"
              ]
            }
          ]
        },
        {
          "name":"Brown Nuts",
          "children":[
            {
              "name":"Normal Nuts",
              "children":[
                "Hazelnuts"
              ]
            }
          ]
        }
      ]
    }
  ]
}

我是如何尝试重组数据的:

var materialData = {
  'name': 'Big Data',
  'children': []
};


var numberOfElements = data.children.length;

for (var i = 0; i < numberOfElements; i++) {
  var elemObject = data.children.slice(i, i + 1),
    elemInArray = elemObject[0],
    elem = {},
    elem = elemInArray;
  var name = elem.name,
    preview = elem.preview,
    group1 = elem.gruppe_1,
    group2 = elem.gruppe_2,
    group3 = elem.gruppe_3,
    group4 = elem.gruppe_4,
    group5 = elem.gruppe_5;


  // group 1
  var group = {
    'name': group1,
    // 'parent': 'Material Archiv',
    'children': []
  }
  // get first layer groups
  if (i != 0) {
    if (group.name != data.children[i - 1].gruppe_1) {
      materialData.children.push(group)
    }
  } else if (i === 0) {
    materialData.children.push(group)
  }

  // group 2
  var group = {
    'name': group2,
    // 'parent': 'Material Archiv',
    'children': []
  }

  var aboveGroupPosition = materialData.children.map(function(g) {
    return g.name;
  }).indexOf(group1);

  // get second layer groups
  if (group2) {
    if (i != 0) {
      if (group.name != data.children[i - 1].gruppe_2) {
        materialData.children[aboveGroupPosition].children.push(group)
      }
    } else if (i === 0) {
      materialData.children[aboveGroupPosition].children.push(group)
    }
  }

  // group 3
  var group = {
    'name': group3,
    // 'parent': '',
    'children': []
  }

  var aboveGroupPositionThirdLayer = materialData.children[aboveGroupPosition].children.map(function(g) {
    return g.name;
  }).indexOf(group2);

  // get third layer groups
  if (group3) {
    var checkGroup3 = function(recentName) {
      for (var j = 0; j < materialData.children.length; j++) {
        for (var k = 0; k < materialData.children[j].children.length; k++) {
          console.log(_.find(materialData.children[j].children[k].children, {
            'name': recentName
          }));
          if (!_.find(materialData.children[j].children[k].children, {
              'name': recentName
            })) {
            //console.log(recentName);
          }
        }
      }
    }
    checkGroup3(); // this function was a try to get the group3 names once, failed
    if (i != 0) {
      if (group.name != data.children[i - 1].gruppe_3) { // error here. Condition checks the group 3 aka "gruppe_3" multiple times because in first round the group name isnt in the json, then another group name follows, is also not in json but then the first one comes again and the group name isnt again like the grupp_3 name and get pushed to the json again.
        materialData.children[aboveGroupPosition].children[aboveGroupPositionThirdLayer].children.push(group)
      }
    } else if (i === 0) {
      materialData.children[aboveGroupPosition].children[aboveGroupPositionThirdLayer].children.push(group)
    }
  }

}

console.log(materialData);

最佳答案

一种方法。

您可以通过迭代嵌套组的键并搜索组来采用迭代方法。如果未找到,则生成一个包含子项的新组并继续,直到所有组都在对象中。

最后将 name 属性分配给一个新的组,在可能的后续对象之前。

var data = { name: "Big Data", children: [{ name: "Apple", gruppe_1: "Fruits", gruppe_2: "Red Fruits", gruppe_3: "Tree Fruits", gruppe_4: "Winter Favourite Fruits", gruppe_5: "Candy Fruits" }, { name: "Pomegranate", gruppe_1: "Fruits", gruppe_2: "Red Fruits", gruppe_3: "Tree Fruits", gruppe_4: "Winter Favourite Fruits", gruppe_5: "Candy Fruits" }, { name: "Pear", gruppe_1: "Fruits", gruppe_2: "Green Fruits", gruppe_3: "Medium Tree Fruits" }, { name: "Strawberry", gruppe_1: "Nuts", gruppe_2: "Red Nuts", gruppe_3: "Awkward Nuts" }, { name: "Hazelnuts", gruppe_1: "Nuts", gruppe_2: "Brown Nuts", gruppe_3: "Normal Nuts" }, { name: "Cucumber", gruppe_1: "Vegetable", gruppe_2: "Green Vegetable", gruppe_3: "Long Vegetable" }, { name: "Maracuya" }, { name: "Green Kiwi", gruppe_1: "Fruits", gruppe_2: "Green Fruits" }, { name: "Cherry", gruppe_1: "Fruits", gruppe_2: "Red Fruits", gruppe_3: "Tree Fruits" }] },
    result = { name: data.name, children: [] };

data.children.forEach(function (object) {
    const getKey = i => 'gruppe_' + i;

    var i = 1, index,
        level = result.children,
        temp,
        key = getKey(i);

    while (key in object) {
        temp = level.find(({ name }) => object[key] === name);
        if (!temp) {
            temp = { name: object[key], children: [] };
            level.push(temp);
        }
        level = temp.children;
        key = getKey(++i);
    }
    index = level.findIndex(o => typeof o === 'object');
    level.splice(index === -1 ? level.length : index, 0, object.name);
});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

关于javascript - 将子组中的名称排序为组 - 重组 json 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48809757/

相关文章:

javascript - redux - 如何存储和更新键/值对

javascript - lodash 集合 - 在集合的现有对象中添加额外的自定义属性

javascript - 两个物体的深度差异

javascript - 获取父数组及其所有子数组

javascript - 如何让 Highchart 填满整个 bootstrap 窗口?

javascript - 为什么 Eleventy 尝试解析直通副本中的文件?

javascript - onchange 事件是否传播?

d3.js - 将 D3 与 Angular-cli 集成

javascript - d3 中的鼠标输入

javascript - d3.event 在 debounced 函数中为 null