将数据格式化为新结构javascript

时间:2016-11-09 15:35:36

标签: javascript d3.js

我目前正在与D3合作进行实验,我以某种格式从API接收数据,但是我需要将数据重组为与下面的D3一起使用的格式,这是我收到的数据的示例

{
    "user_id": 3,
    "service_user": "Phillippa",
    "staff_name": "Abbey",
    "role": "A",
    "staff_id": 2,
    "status": "P",
    "workbase": "Workbase 1"
},
{
    "user_id": 60,
    "service_user": "Raymond",
    "staff_name": "Adam",
    "role": "D",
    "staff_id": 8,
    "status": "C",
    "workbase": "Workbase 2"
},
{
    "user_id": 63,
    "service_user": "Alison",
    "staff_name": "Adam",
    "role": "D",
    "staff_id": 8,
    "status": "C",
    "workbase": "Workbase 2"
},
{
    "user_id": 68,
    "service_user": "Philippa",
    "staff_name": "Adam",
    "role": "C",
    "staff_id": 9,
    "status": "C",
    "workbase": "Workbase 2"
},
{
    "user_id": 57,
    "service_user": "Philip",
    "staff_name": "Adam",
    "role": "W",
    "staff_id": 9,
    "status": "C",
    "workbase": "Workbase 2"
}

结构D3期待跟随,

{
    "name":"flare",
    "children":[
        {
            "name":"analytics",
            "children":[
                {
                    "name":"cluster",
                    "children":[
                        {
                            "name":"AgglomerativeCluster",
                            "size":3938
                        },
                        {
                            "name":"CommunityStructure",
                            "size":3812
                        },
                        {
                            "name":"HierarchicalCluster",
                            "size":6714
                        },
                        {
                            "name":"MergeEdge",
                            "size":743
                        }
                    ]
                },
                {
                    "name":"graph",
                    "children":[
                        {
                            "name":"BetweennessCentrality",
                            "size":3534
                        },
                        {
                            "name":"LinkDistance",
                            "size":5731
                        },
                        {
                            "name":"MaxFlowMinCut",
                            "size":7840
                        },
                        {
                            "name":"ShortestPaths",
                            "size":5914
                        },
                        {
                            "name":"SpanningTree",
                            "size":3416
                        }
                    ]
                },
                {
                    "name":"optimization",
                    "children":[
                        {
                            "name":"AspectRatioBanker",
                            "size":7074
                        }
                    ]
                }
            ]
        }
    ]
}

所以我需要使用接收到的数据来生成一个新的结构,它基本上是带有子数组的对象。

第一个结构的工作方式是Workbase 1,有1个孩子" Abbey",反过来" Abbey"有一个孩子" Phillipa",现在可能Workbase 1在返回的数据中多次出现,所以它只需要推入Workbase 1特定对象。

Workbase 2稍微复杂一点,Workbase 2有一个孩子" Adam"和"亚当"有4个孩子" Raymond"," Allison"," Phillipa"和" Phillip"。

理论上,数据应如下所示,

{
    "name":"Workbase 1",
    "children":[
        {
            "name":"Abbey",
            "children":[
                {
                    "name":"Phillipa"
                }
            ]
        }
    ]
},
{
    "name":"Workbase 2",
    "children":[
        {
            "name":"Adam",
            "children":[
                {
                    "name":"Raymond"
                },
                {
                    "name":"Allison"
                },
                {
                    "name":"Phillipa"
                },
                {
                    "name":"Phillip"
                }
            ]
        }
    ]
}

到目前为止,我正在遍历该对象并确保我只获得独特的工作区,

original_data.forEach(function(j){
    if(_.indexOf(workbases, j.workbase) < 0) {
        workbases.push(j.workbase);

        data.push({
            name : j.workbase,
            children : []
        });
    }
});

从这一点来说,我无法找到正确的儿童和儿童的孩子进入正确的工作基础,任何想法?

2 个答案:

答案 0 :(得分:0)

您可以使用带有哈希表的嵌套方法来表示名称。

var data = [{ "user_id": 3, "service_user": "Phillippa", "staff_name": "Abbey", "role": "A", "staff_id": 2, "status": "P", "workbase": "Workbase 1" }, { "user_id": 60, "service_user": "Raymond", "staff_name": "Adam", "role": "D", "staff_id": 8, "status": "C", "workbase": "Workbase 2" }, { "user_id": 63, "service_user": "Alison", "staff_name": "Adam", "role": "D", "staff_id": 8, "status": "C", "workbase": "Workbase 2" }, { "user_id": 68, "service_user": "Philippa", "staff_name": "Adam", "role": "C", "staff_id": 9, "status": "C", "workbase": "Workbase 2" }, { "user_id": 57, "service_user": "Philip", "staff_name": "Adam", "role": "W", "staff_id": 9, "status": "C", "workbase": "Workbase 2" }],
    result = [];

data.forEach(function (a) {
    var check = function (key, target) {
            if (!this[key]) {
                this[key] = { name: key, children: [] };
                target.push(this[key]);
            }
        }.bind(this);

    check(a.workbase, result);
    check(a.staff_name, this[a.workbase].children);
    this[a.staff_name].children.push({ name: a.service_user });
}, Object.create(null));

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

答案 1 :(得分:0)

let sorted = original_data.reduce((acc, cur) => {
  /* check if the workbase is already in the array */
  let wb = acc.find(wb => wb.name === cur.workbase);
  if (wb) {
    /* check if staff by that name is already in this workbase */
    let staff = wb.children.find(staff => staff.name === cur.staff_name);
    if (staff) {
      staff.children.push({name: cur.service_user});
    } else {
      /* if not, instantiate this staff in the array */
      wb.push({
        name: cur.staff_name,
        children: [{name: cur.service_user}]
      });
    }
  } else {
    /* if not, instantiate this workbase in the array */
    acc.push({
      name: cur.workbase,
      children: [
        {
          name: cur.staff_name,
          children: [{name: cur.service_user}]
        }
      ]
    });
  }
  return acc;
}, []);