在javascript中转换为分层数组

时间:2015-01-30 11:26:59

标签: javascript jquery arrays object d3.js

Fiddle Example

我想转换此JSON数据

var data = [
  {
    "computer": 24,
    "brand": "Italy A",
    "phone": 0,
    "country": "Italy"
  },
  {
    "brand": "Italy C",
    "computer": 0,
    "phone": 0,
    "country": "Italy"
  },
  {
    "brand": "Brazil B",
    "computer": 0,
    "phone": 22,
    "country": "Brazil"
  },
  {
    "computer": 0,
    "brand": "Brazil D",
    "phone": 62,
    "country": "Brazil"
  },
  {
    "computer": 34,
    "brand": "US E",
    "phone": 41,
    "country": "US"
  }
];

d3图表的分层表单:

{
  "name": "categories",
  "children": [
    {
      "name": "phone",
      "children": [
        {
          "name": "US",
          "children": [
            {
              "brand": "US E",
              "size": 41
            }
          ]
        },
        {
          "name": "Brazil",
          "children": [
            {
              "brand": "Brazil B",
              "size": 22
            },
            {
              "brand": "Brazil D",
              "size": 62
            }
          ]
        },
        {
          "name": "Italy",
          "children": []
        }
      ]
    },
    {
      "name": "computer",
      "children": [
        {
          "name": "US",
          "children": [
            {
              "brand": "US E",
              "size": 34
            }
          ]
        },
        {
          "name": "Brazil",
          "children": []
        },
        {
          "name": "Italy",
          "children": [
            {
              "brand": "Italy A",
              "size": 24
            }
          ]
        }
      ]
    }
  ]
}

我想出了这段代码来生成格式:

function group_children(data){
    var categories = ["phone","computer"];
    var countries = ["US","Brazil","Italy"];
    var object = {name:"categories",children:[]};
    for(var c =0; c < categories.length;c++){
      object.children.push({"name":categories[c],children:[]});

     for(var con = 0;con < countries.length;con++){
       object.children[c].children.push({"name":countries[con],"children":[]});
     }
    }

    for(var i = 0;i < data.length;i++){
     var row = data[i];
     for(var c =0; c < categories.length;c++){
      for(var con = 0;con < countries.length;con++){
        var cat_key = categories[c],
            country_key = countries[con];
        if(row[cat_key] > 0){
          if(object.children[c].name == cat_key && row.country == country_key){  object.children[c].children[con].children.push({brand:row["brand"],size:row[cat_key]});        
          }
        }
      }   
    }
 }
 return object;
}

如果国家的children数组为空,是否有可能在迭代期间不将国家/地区推入品牌或计算机的children数组?

例如,应删除这些对象

        // computer
        {
          "name": "Brazil",
          "children": []
        }
        // phone:

        {
          "name": "Italy",
          "children": []
        }

以下是将每个国家/地区推送到每个类别的子数组中的部分:

    for(var c =0; c < categories.length;c++){
      object.children.push({"name":categories[c],children:[]});

     for(var con = 0;con < countries.length;con++){
       object.children[c].children.push({"name":countries[con],"children":[]});
     }
    }

我的方法可能是错误的,因此也欢迎将数据转换为分层结构的任何其他建议。

3 个答案:

答案 0 :(得分:2)

选中此fiddle,这是您正在寻找的内容吗?我决定采用与你所遵循的方法不同的方法,希望你不要介意。我对代码进行了评论,以便更清楚:

var result = {
    name: "categories",
    children: [{
        "name": "phone",
            "children": []
    }, {
        "name": "computer",
            "children": []
    }]
};

$.each(data, function (index, item) {// Go through data and populate the result object.
    if (+item.computer > 0) { // Computer has items.
        filterAndAdd(item, result.children[1], "computer");
    }
    if (+item.phone > 0) { // Phone has items.
        filterAndAdd(item, result.children[0], "phone");
    }
});

function filterAndAdd(item, result_place, type) {// Search and populate.
    var i = -1;
    $.each(result_place.children, function (index,a) {
        if( a.name === item.country ) {
            i = index;
            return false;
        }
    });

    if (i > -1) {// Country already exists, add to children array.
        result_place.children[i].children.push({
            "brand": item.brand,
                "size": item[type]
        });
    } else {// Country doesn't exist, create it.
        result_place.children.push({
            "name": item.country,
                "children": [{
                "brand": item.brand,
                    "size": item[type]
            }]
        });
    }
}

希望它有所帮助。

答案 1 :(得分:0)

您必须使用d3.nest()函数按层次结构对数组元素进行分组。文档可用 here。还可以查看this教程,它可以帮助您创建分层数据。

这还不够,您可以根据键和值对获得分层数据。但是如果你想转换成名字和孩子,已经提出了关于SO的问题,请检查this

答案 2 :(得分:0)

使用当前的方法,您应该在推送国家之前迭代数据以找到空数据,这将导致更多的迭代,而不仅仅是简单地迭代结果以过滤空的结果。

否则,您应该在数据插入的相同迭代中创建scruture,从而将迭代减少到1.