D3.nest()没有给我我需要的数据结构

时间:2016-01-22 23:58:00

标签: javascript d3.js

我正在使用D3并且无法按照我需要的方式嵌套数据。我将尝试将场景简化为此问题的本质。

我将费用数据保存到变量expenses。数组中的每个对象代表特定日期在特定实体店的单次购买。 (“StoreID”是唯一的;为简洁起见,我省略了街道地址):

// original data

var expenses =

   [
     {"storeID":"4872379","storeName":"Gap","zipCode":"10032","amount":34.88,"date":"11/12/2015"},
     {"storeID":"4872379","storeName":"Gap","zipCode":"10032","amount":-34.88,"date":"11/15/2015"},
     {"storeID":"2209875","storeName":"Banana Republic","zipCode":"10003","amount":1650.54,"date":"12/01/2015"},
     {"storeID":"5434432","storeName":"Gap","zipCode":"10031","amount":120.11,"date":"11/18/2015"},
     {"storeID":"5434432","storeName":"Gap","zipCode":"10031","amount":45.5,"date":"12/01/2015"},
     {"storeID":"5434432","storeName":"Gap","zipCode":"10031","amount":117.08,"date":"12/01/2015"}
   ]

我想要做的是将amount / date对作为每个唯一商店的单个数组中的对象。这就是我想要的结果:

// desired structure

  [
    {"key":"2209875",
     "storeName":"BananaRepublic",
     "zipCode":"10003",
     "values": [
       {"amount":1650.54,
        "date":"12/01/2015"}]
    },
    {"key":"4872379",
     "storeName":"Gap",
     "zipCode":"10032",
     "values": [
        {"amount":34.88,
         "date":"11/12/2015"},
        {"amount":-34.88,
         "date":"11/15/2015"}]
    }, 
    {"key":"5434432",
     "storeName":"Gap",
     "zipCode":"10031",
     "values": [
       {"amount":120.11,
        "date":"11/18/2015"},
       {"amount":45.5,
        "date":"12/01/2015"},
       {"amount":117.08,
        "date":"12/01/2015"}]
    }
  ]

使用d3.nest(),我只能做到这一点:

 // getting closer

 var expensesByStoreID = d3.nest()
   .key(function(d) { return d.storeID; })
   .entries(expenses);

 // expensesByStoreID holds this:

[
  {"key":"2209875",
   "values": [
      {"storeID":"2209875",
       "storeName":"BananaRepublic",
       "zipCode":"10003",
       "amount":1650.54,
       "date":"12/01/2015"}]
  },
  {"key":"4872379",
   "values": [
      {"storeID":"4872379",
       "storeName":"Gap",
       "zipCode":"10032",
       "amount":34.88,
       "date":"11/12/2015"},
      {"storeID":"4872379",
       "storeName":"Gap",
       "zipCode":"10032",
       "amount":-34.88,
       "date":"11/15/2015"}]
   }, 
   {"key":"5434432",
    "values": [
       {"storeID":"5434432",
        "storeName":"Gap",
        "zipCode":"10031",
        "amount":120.11,
        "date":"11/18/2015"},
       {"storeID":"5434432",
        "storeName":"Gap",
        "zipCode":"10031",
        "amount":45.5,
        "date":"12/01/2015"},
       {"storeID":"5434432",
        "storeName":"Gap",
        "zipCode":"10031",
        "amount":117.08,
        "date":"12/01/2015"}]
    }
]

每个amountdate在一个对象中,但商店详细信息也在那里,重复。我希望每个商店对象只存储一次商店详细信息。它成为一个效率问题,因为数据库包含数千个商店和购买。

我的d3.nest()代码中是否有可以更改的内容?是否有一个简单的Javascript函数可以将我的数据结构从“原始”转变为“所需”?任何帮助,将不胜感激。 : - )

2 个答案:

答案 0 :(得分:1)

你可以这样做:



var expenses =

   [
     {"storeID":"4872379","storeName":"Gap","zipCode":"10032","amount":34.88,"date":"11/12/2015"},
     {"storeID":"4872379","storeName":"Gap","zipCode":"10032","amount":-34.88,"date":"11/15/2015"},
     {"storeID":"2209875","storeName":"Banana Republic","zipCode":"10003","amount":1650.54,"date":"12/01/2015"},
     {"storeID":"5434432","storeName":"Gap","zipCode":"10031","amount":120.11,"date":"11/18/2015"},
     {"storeID":"5434432","storeName":"Gap","zipCode":"10031","amount":45.5,"date":"12/01/2015"},
     {"storeID":"5434432","storeName":"Gap","zipCode":"10031","amount":117.08,"date":"12/01/2015"}
   ];

expensesByStoreID = d3.nest()
        .key(function(d) {
            return d.storeID;//group by store id
        })
        .entries(expenses);
//now designing the data output of nest into your desired format 
    var data = expensesByStoreID.map(function(d) {
        return {
            key: {
                storeID: d.key,//changing the key structure
                storeName: d.values[0].storeName,
                zipCode: d.values[0].zipCode
            },
            values: d.values.map(function(k) {
                return {
                    amount: k.amount, //changing the values structure
                    date: k.date
                }
            })
        };
    })
    console.log(data);
document.body.appendChild(document.createElement('pre')).innerHTML = JSON.stringify(data, null, 2)

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

实际上,这给了我正在寻找的结构:

var data = expensesByStoreID.map(function(d) {
    return {storeID: d.key,
            storeName: d.values[0].storeName,
            zipCode: d.values[0].zipCode,
            values: d.values.map(function(k) {
                return { amount: k.amount,
                         date: k.date
                       }
                   })
            }
        })

document.body.appendChild(document.createElement('pre')).innerHTML = JSON.stringify(data, null, 2)

[
  {
    "storeID": "2209875",
    "storeName": "Banana Republic",
    "zipCode": "10003",
    "values": [
      {
        "amount": 1650.54,
        "date": "12/01/2015"
      }
    ]
  },
  {
    "storeID": "4872379",
    "storeName": "Gap",
    "zipCode": "10032",
    "values": [
      {
        "amount": 34.88,
        "date": "11/12/2015"
      },
      {
        "amount": -34.88,
        "date": "11/15/2015"
      }
    ]
  },
  {
    "storeID": "5434432",
    "storeName": "Gap",
    "zipCode": "10031",
    "values": [
      {
        "amount": 120.11,
        "date": "11/18/2015"
      },
      {
        "amount": 45.5,
        "date": "12/01/2015"
      },
      {
        "amount": 117.08,
        "date": "12/01/2015"
      }
    ]
  }
]