i'm trying combine 2 arrays of objects, based on 2 properties, , rewrite names of other properties in joined dataset.
this datasets like:
var xdata = [ { row_id: 1, date: '2013-04-01', cost: 18 }, { row_id: 2, date: '2013-04-01', cost: 27 } ... ]; var ydata = [ { row_id: 1, date: '2013-04-01', cost: 48 }, { row_id: 3, date: '2013-04-01', cost: 37 } ... ]; the properties want join on row_id , date properties, , want rewrite cost x_cost , y_cost respectively. want deal missing values. want end with:
var combineddata = [ { row_id: 1, date: '2013-04-01', x_cost: 18, y_cost: 48 }, { row_id: 2, date: '2013-04-01', x_cost: 27, y_cost: null }, { row_id: 3, date: '2013-04-01', x_cost: null, y_cost: 37 } ... ]; this code right now. it's pretty horrible:
combinexandydatasets: function(xdata, ydata) { // index both datasets id , date. var x_indexed_by_id_and_date = {}; xdata.foreach(function(d) { var k = d.row_id + '_' + d.date; x_indexed_by_id_and_date[k] = d; }); var y_indexed_by_id_and_date = {}; ydata.foreach(function(d) { var k = d.row_id + '_' + d.date; y_indexed_by_id_and_date[k] = d; }); var combineddata = []; // iterate on ydata, join xdata if possible. (var row_id in y_indexed_by_id_and_date) { var row = json.parse(json.stringify(y_indexed_by_id_and_date[row_id])); row.y_cost = +y_indexed_by_id_and_date[row_id].cost; if (row_id in x_indexed_by_id_and_date) { row.x_cost = +x_indexed_by_id_and_date[row_id].cost; } else { row.x_cost = null; } combineddata.push(row); } // iterate on xdata, add wasn't in ydata. (var x_row_id in x_indexed_by_id_and_date) { if (!(x_row_id in y_indexed_by_id_and_date)) { var x_row = json.parse(json.stringify(x_indexed_by_id_and_date[x_row_id])); x_row.y = null; x_row.x = +x_row.cost; combineddata.push(x_row); } } return combineddata; } what can make less awful?
i'm using jquery, , add e.g. underscore if help.
you take advantage of reduce reduce each array dictionary , convert dictionary array. (vanilla js, not ie 8 compatible out-of-the-box):
var xdata = [ { row_id: 1, date: '2013-04-01', cost: 18 }, { row_id: 2, date: '2013-04-01', cost: 27 } ]; var ydata = [ { row_id: 1, date: '2013-04-01', cost: 48 }, { row_id: 3, date: '2013-04-01', cost: 37 } ]; var xdatadict = xdata.reduce(function(p,c) { createdictionaryentry(p,c,c.cost,null) return p; },{}); xandydatadict = ydata.reduce(function(p,c) { createdictionaryentry(p,c,null,c.cost) return p; }, xdatadict); var combineddata = object.keys(xandydatadict).map(function(key) { return xandydatadict[key]; }); alert(json.stringify(combineddata)); function createdictionaryentry(p,c,x_cost,y_cost) { var key = c.row_id + "-" + c.date; if (p[key]) { p[key].x_cost = p[key].x_cost || x_cost; p[key].y_cost = p[key].y_cost || y_cost; } else { p[key] = { row_id: c.row_id, date: c.date, x_cost: x_cost, y_cost: y_cost } } } note combineddata won't in guaranteed order, if that's important, can sort afterwards.
using underscore:
var xdata = [ { row_id: 1, date: '2013-04-01', cost: 18 }, { row_id: 2, date: '2013-04-01', cost: 27 } ]; var ydata = [ { row_id: 1, date: '2013-04-01', cost: 48 }, { row_id: 3, date: '2013-04-01', cost: 37 } ]; var xdatadict = _.reduce(xdata, function(p,c) { createdictionaryentry(p,c,c.cost,null) return p; },{}); xandydatadict = _.reduce(ydata,function(p,c) { createdictionaryentry(p,c,null,c.cost) return p; }, xdatadict); var combineddata = _.map(object.keys(xandydatadict),function(key) { return xandydatadict[key]; }); alert(json.stringify(combineddata)); function createdictionaryentry(p,c,x_cost,y_cost) { var key = c.row_id + "-" + c.date; if (p[key]) { p[key].x_cost = p[key].x_cost || x_cost; p[key].y_cost = p[key].y_cost || y_cost; } else { p[key] = { row_id: c.row_id, date: c.date, x_cost: x_cost, y_cost: y_cost } } } <script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
Comments
Post a Comment