2

What I want to do is grab a bunch of different sets of date:value pairs, join them together based on the date, and fill in missing values with null if the dates don't match.

Like this as input:

{"series1":[{'date1':4},{'date2':2},{'date3':6}]}
{"series2":[{'date1':5},{'date2':3},{'date3':4},{'date4':6}]}
{"series3":[{'date2':1},{'date4':9}]}

to get:

{"output":[{'date1':[4,5,]},{'date2':[2,3,1]},{'date3':[6,4,]},{'date4':[,6,9]}]}

Or looking at it another way, I want to be able to organize data like this:

table format of data

No matter how many series I'll have, and no matter where any gaps may be.

I found this question: SQL style JOIN on JSON data, but I'm not sure how to extend that solution to what I need. I could add some extra logic and then run it n-1 times if that's what has to be done, but it really feels like something much simpler and elegant would exist for this purpose.

Community
  • 1
  • 1
UnLucky
  • 23
  • 4
  • as a note, object values like what you have here `{'date1',4}` can't be comma separated, you need to format them like this `{'date1' : 4}` – Ryan Feb 12 '13 at 22:11
  • oh right, I originally had them as `['date',4,5,]` but found it a bit messy that way. didn't change it all over properly, oops – UnLucky Feb 12 '13 at 22:26

2 Answers2

0

If you have the dates like this:

var t = {
    "series1":[{'date1':4},{'date2':2},{'date3':6}],
    "series2":[{'date1':5},{'date2':3}, {'date3':4},{'date4':6}],
    "series3":[{'date2':1},{'date4':9}]
}

Then this should work:

var output = {};

function getKeys (obj) {
    var keys = [];
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            keys.push(key);
        }
    }
    return keys;
}

getKeys(t).forEach(function (val) {
    t[val].forEach(function (ser) {
        var date = getKeys(ser)[0];
        if (!output.hasOwnProperty(date)) {
            output[date] = [];
        }
        output[date].push(ser[date]);
    });
});

console.log(output);

And you will get it in this format

Object {date1: Array[2], date2: Array[3], date3: Array[2], date4: Array[2]}
    date1: Array[2]
    date2: Array[3]
    date3: Array[2]
    date4: Array[2]

if you want your original dates in this format

var original = [
    {"series1":[{'date1':4},{'date2':2},{'date3':6}]},
    {"series2":[{'date1':5},{'date2':3},{'date3':4},{'date4':6}]},
    {"series3":[{'date2':1},{'date4':9}]}
];

Then add this after the getKeys function

var t = {},
    output = {};

original.forEach(function (obj) {
    var prop = getKeys(obj)[0];
    if (! t.hasOwnProperty(prop) ) {
        t[prop] = {}
    }
    t[prop] = obj[prop];
});
richie
  • 2,448
  • 3
  • 19
  • 21
  • Any way to push a blank value for each series if there wasn't a value for the given date? To always get `Array[3]` in this case, like `0:4, 1:5, 2:` – UnLucky Feb 12 '13 at 23:33
  • @UnLucky define the blank values as e.g false, null, or empty string. They will then be added to the output, but without any number given – richie Feb 12 '13 at 23:55
0

Here is one way to approach this. Iterate through your series, and for each unique date, make a reference in an object. Then append to that reference as your encounter it.

js:

var obj = {'series1':[{'date1':4},{'date2':2},{'date3':6}],
'series2':[{'date1':5},{'date2':3},{'date3':4},{'date4':6}],
'series3':[{'date2':1},{'date4':9}]};
console.log(obj);
var output = {};
for(var series in obj ){
    var dateObjects = obj[series];
    for( var dateObj in dateObjects ){
        var dates = dateObjects[dateObj];
        for( var date in dates ){
         if( typeof output[date] == "undefined" ){
          output[date] = [];
         }
         output[date].push(dates[date]);
        }
    }
}
console.log(output);

demo: http://jsfiddle.net/Z4ejj/

Travis J
  • 81,153
  • 41
  • 202
  • 273