1

The original JSON file:

{
"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": {}}

I want to change the structure to:

{
"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": {}}

Basically, I want to put all the count of the same hub under the same array. How do I come about doing this?

In terms of huge amount of data, will changing the JSON to the new file make the loading speed longer as compared to making JS looping through the original file to build a dashboard?

7
  • 3
    Is there any good reason why you're using size1, size2, size3, ... instead of an array? Commented Jun 3, 2016 at 6:18
  • Do you want to add the count? Commented Jun 3, 2016 at 6:19
  • @Andreas Hi, I am building dashboard using d3.js and I am new to JS. It will save me alot of trouble by changing the JSON to the new file. Shown in a separate question (stackoverflow.com/questions/37585220/…) Commented Jun 3, 2016 at 6:22
  • @DushyantBangal, in the new file, the new name is size1, size2 to size4. They will contain the count. Do you have any better suggestion as to which data structure will be the best? Thanks! Commented Jun 3, 2016 at 6:24
  • @Shawn a sizes array with size1 value @ sizes[0], size2 value @ sizes[1] etc... would be better i suppose. I will prepare an answer accordingly. Commented Jun 3, 2016 at 8:15

2 Answers 2

2

You can iterate and take an object as reference to the result array.

The elements of size": "0" go to 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);

Sign up to request clarification or add additional context in comments.

2 Comments

thanks so much, I will accept your answer as soon as I finish breaking down your method. Learning jquery now.
there is no jquery in it. $scope is just a variable.
1

Hi this is my answer according to my proposal with sizes array in which each size.count is located at the index corresponding to the size value. i.e. size: 0 count : 2082 is placed like [2082,,,] in the array. To access the size and count you can do like count = sizes[size] The code is as follows;

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);

I first construct a reduced object which can also be used for your purposes but then i map this object into an array so that the data is in the array of objects form. You can use whichever form of data you like the best.

The slightly confusing part might be the (new Array(c.size*1)).concat(c.count) instruction. There we are creating a new object (through object literal) and we have to initiate a sparse sizes array with only one value inserted at the index position designated by the size value. So we construct a new Array of size (new Array(c.size*1)) however our c.size value is of string type. If we do like new Array("2") then we will receive an array with one string item ("2") at index 0. But we want an array in the size of 2. That's why we convert string "2" to number 2 by "2"*1 operation (multiplication operator type coerces string into number). So we receive an empty array of size 2. Now comes the concat operation which attaches our size value to the correct index location in the resulting array.

It's essentially the unification of the following two instructions

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

2 Comments

Thanks, 1 question though, is it advisable to use the word "new". From w3 basic tutorial it is recommended that we should not use "new".
In JS if you call a function with the new operator to create an object, it means that you are using a constructor function and the constructor's prototype gets assigned to the prototype of the instantiated object. However if you don't use new that's a simple function call and whatever that function (Array() in this case) would return, that gets assigned to your variable. Array function can be called as constructor or factory (just returns an empty [] in the size designated by the argument) In array case there is no difference. For me it's best practice to use new. There is no harm of it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.