【问题标题】:Edit JSON data structure using JS使用 JS 编辑 JSON 数据结构
【发布时间】:2016-06-03 06:16:03
【问题描述】:

原始 JSON 文件:

{
"data": {
    "count_at_hub": [
        {
            "hub": "A",
            "date": "",
            "size": "1",
            "count": 141
        },
        {
            "hub": "A",
            "date": "",
            "size": "2",
            "count": 44
        },
        {
            "hub": "A",
            "date": "",
            "size": "3",
            "count": 3
        },
        {
            "hub": "A",
            "date": "",
            "size": "0",
            "count": 1446
        },
        {
            "hub": "B",
            "date": "",
            "size": "1",
            "count": 202
        },
        {
            "hub": "B",
            "date": "",
            "size": "0",
            "count": 2082
        },
        {
            "hub": "B",
            "date": "",
            "size": "3",
            "count": 11
        },
        {
            "hub": "B",
            "date": "",
            "size": "2",
            "count": 53
        }
    ],
    "Part B":[
        {

        }
    ]
},
"success": true,
"errors": [],
"e": {}}

我想把结构改成:

{
"data": {
    "count_at_hub": [
        {
            "hub": "A",
            "date": "",
            "size1": 141,
            "size2": 44,
            "size3": 3,
            "size4": 1446
        },

        {
            "hub": "B",
            "date": "",
            "size1": 202,
            "size2": 2082,
            "size3": 11,
            "count": 53
        }
    ],
    "Part B":[
        {

        }
    ]
},
"success": true,
"errors": [],
"e": {}}

基本上,我想将同一个集线器的所有计数放在同一个数组下。我是怎么做到的?

在数据量巨大的情况下,相比于让JS循环遍历原始文件构建仪表盘,将JSON更改为新文件会导致加载速度更长吗?

【问题讨论】:

  • 你有什么好的理由使用size1, size2, size3, ...而不是数组?
  • 要添加计数吗?
  • @Andreas 嗨,我正在使用 d3.js 构建仪表板,我是 JS 新手。通过将 JSON 更改为新文件,它将为我省去很多麻烦。显示在单独的问题中 (stackoverflow.com/questions/37585220/…)
  • @DushyantBangal,在新文件中,新名称为size1, size2 to size4。它们将包含计数。您对哪种数据结构最好有更好的建议吗?谢谢!
  • @Shawn 一个 sizes 数组,其 size1 值@sizes[0],size2 值@sizes[1] 等...我想会更好。我会相应地准备一个答案。

标签: javascript arrays json d3.js


【解决方案1】:

您可以迭代并将对象作为对结果数组的引用。

size": "0" 的元素转到size4

var object = { "data": { "count_at_hub": [{ "hub": "A", "date": "", "size": "1", "count": 141 }, { "hub": "A", "date": "", "size": "2", "count": 44 }, { "hub": "A", "date": "", "size": "3", "count": 3 }, { "hub": "A", "date": "", "size": "0", "count": 1446 }, { "hub": "B", "date": "", "size": "1", "count": 202 }, { "hub": "B", "date": "", "size": "0", "count": 2082 }, { "hub": "B", "date": "", "size": "3", "count": 11 }, { "hub": "B", "date": "", "size": "2", "count": 53 }], "Part B": [{}] }, "success": true, "errors": [], "e": {} },
    temp = [];

object.data.count_at_hub.forEach(function (a) {
    if (!this[a.hub]) {
        this[a.hub] = { hub: a.hub, date: a.date, size1: 0, size2: 0, size3: 0, size4: 0 };
        temp.push(this[a.hub]);
    }
    this[a.hub]['size' + (+a.size || 4)] += a.count;
}, Object.create(null));

object.data.count_at_hub = temp;

console.log(object);

【讨论】:

  • 非常感谢,我会在完成分解您的方法后立即接受您的回答。现在学习jquery。
  • 里面没有jquery。 $scope 只是一个变量。
【解决方案2】:

您好,这是我根据我的建议的答案,其中每个 size.count 都位于与 size 值对应的索引处。即size: 0 count : 2082[2082,,,] 一样放置在数组中。要访问大小和计数,您可以像count = sizes[size]一样执行代码如下;

var cag =  [
        {
            "hub": "A",
            "date": "",
            "size": "1",
            "count": 141
        },
        {
            "hub": "A",
            "date": "",
            "size": "2",
            "count": 44
        },
        {
            "hub": "A",
            "date": "",
            "size": "3",
            "count": 3
        },
        {
            "hub": "A",
            "date": "",
            "size": "0",
            "count": 1446
        },
        {
            "hub": "B",
            "date": "",
            "size": "1",
            "count": 202
        },
        {
            "hub": "B",
            "date": "",
            "size": "0",
            "count": 2082
        },
        {
            "hub": "B",
            "date": "",
            "size": "3",
            "count": 11
        },
        {
            "hub": "B",
            "date": "",
            "size": "2",
            "count": 53
        }
    ],
   reduced = cag.reduce((p,c) => (p[c.hub] ? p[c.hub].sizes[c.size] = c.count
                                           : p[c.hub] = {  "hub": c.hub,
                                                          "date": c.date,
                                                         "sizes": (new Array(c.size*1)).concat(c.count)},
                                  p),{}),
    result = Object.keys(reduced).map(k => reduced[k]);
    console.log(result);

我首先构造了一个简化的对象,它也可以用于您的目的,但然后我将该对象映射到一个数组中,以便数据以对象数组的形式出现。您可以使用您最喜欢的任何形式的数据。

稍微令人困惑的部分可能是(new Array(c.size*1)).concat(c.count) 指令。在那里,我们正在创建一个新对象(通过对象字面量),我们必须启动一个稀疏大小数组,其中只有一个值插入到由大小值指定的索引位置。所以我们构造了一个大小为(new Array(c.size*1)) 的新数组,但是我们的 c.size 值是字符串类型的。如果我们喜欢new Array("2"),那么我们将在索引 0 处收到一个包含一个字符串项 ("2") 的数组。但我们想要一个大小为 2 的数组。这就是我们将字符串 "2" 转换为数字 2 的原因2"*1 运算(乘法运算符类型将字符串强制转换为数字)。所以我们收到一个大小为 2 的空数组。接下来是 concat 操作,它将我们的大小值附加到结果数组中正确的索引位置。

本质上是以下两条指令的统一

    var sizes = [];
sizes[c.size] = c.count;

【讨论】:

  • 谢谢,有 1 个问题,建议使用“新”这个词。从 w3 基础教程开始,建议我们不要使用“new”。
  • 在JS中如果你调用一个带有new运算符的函数来创建一个对象,这意味着你正在使用一个构造函数并且构造函数的原型被分配给实例化对象的原型。但是,如果您不使用new,那么这是一个简单的函数调用,并且无论该函数(在本例中为 Array() )返回什么,都会将其分配给您的变量。数组函数可以作为构造函数或工厂调用(只是返回一个由参数指定的大小的空[])在数组情况下没有区别。对我来说,最好使用new。没有害处。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-11
  • 2022-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多