[英]How to pad and normalize variable length arrays
我有以下圖表數組,其中包含foo,bar和baz對象,每個對象均包含帶有數據點的values數組。
問題是從我的API端點獲得了數量可變的數據點。
我需要規范化我的對象,以便它們:
數據點需要按后面的標簽排序(例如a,b,c ..)
如果數據點在特定對象中不存在,但在任何其他數據點數組中存在,則其值為零
最后,每個對象中的數據點數必須相同。
這是代碼示例:
var r = function() { return Math.random() * 10; };
var chart = [
{key:'foo', values: [['a', r()], ['b', r()], ['c', r()], ['d', r()]]},
{key:'bar', values: [['b', r()], ['c', r()], ['d', r()], ['e', r()]]},
{key:'baz', values: [['c', r()], ['d', r()], ['e', r()], ['f', r()]]}
];
// desired output, where x is the random value returned by r()
// any values that are unavailable must be 0
chart = [
{key:'foo', values: [['a', x], ['b', x], ['c', x], ['d', x], ['e', 0], ['f', 0]]},
{key:'bar', values: [['a', 0], ['b', x], ['c', x], ['d', x], ['e', x], ['f', 0]]},
{key:'baz', values: [['a', 0], ['b', 0], ['c', x], ['d', x], ['e', x], ['f', x]]}
];
您的字母數字對也許可以更好地用對象而不是數組來表示,但是我相信這可以解決上述問題。
var datapointLabels = {}; // Create object to record which labels exist.
for(var i = 0; i < chart.length; i++) { // Iterate through `chart` items.
for(var j = 0; j < chart[i].values.length; j++) { // Iterate through `values` items.
var datapointLabel = chart[i].values[j][0];
datapointLabels[datapointLabel] = true;
}
}
// Skip nested loops above if datapoint labels are pre-known; construct `datapointsLabels` object with one loop, or manually without looping, instead.
var newChart = []; // Must create a new array to hold the padded data (will need to refer to old array throughout process).
for(var i = 0; i < chart.length; i++) {
newChart[i] = {};
newChart[i].key = chart[i].key;
newChart[i].values = [];
for(var datapointLabel in datapointLabels) { // Iterate through all datapoint labels in our records object.
var datapoint = 0; // Set default datapoint as zero.
for(var j = 0; j < chart[i].values.length; j++) { // Look at each `value` pair to see if it matches the current datapoint label.
if(chart[i].values[j][0] === datapointLabel) {
datapoint = chart[i].values[j][1]; // Overwrite default if found.
j = chart[i].values.length; // Skip further checks (optional, minor efficiency increase).
}
}
newChart[i].values.push([datapointLabel, datapoint]); // Push found or default data to new array.
}
}
如果您能夠重新定義數據結構, 則可以使用對象鍵查找方法來切割for
-loop:
var chart = [
{ key: 'foo', values: { a: r(), b: r(), c: r(), d: r() } },
{ key: 'bar', values: { b: r(), c: r(), d: r(), e: r() } },
{ key: 'baz', values: { c: r(), d: r(), e: r(), f: r() } }
];
var datapointLabels = {}; // Create object to record which labels exist.
for(var i = 0; i < chart.length; i++) { // Iterate through `chart` items.
for(var datapointLabel in chart[i].values){ // Iterate through `values` items.
datapointLabels[datapointLabel] = true;
}
}
// Skip nested loops above if datapoint labels are pre-known; construct `datapointsLabels` object with one loop, or manually without looping, instead.
var newChart = []; // Must create a new array to hold the padded data (will need to refer to old array throughout process).
for(var i = 0; i < chart.length; i++) {
newChart[i] = {};
newChart[i].key = chart[i].key;
newChart[i].values = {};
for(var datapointLabel in datapointLabels) { // Iterate through all datapoint labels in records object.
var datapoint = chart[i].values[datapointLabel] || 0;
newChart[i].values[datapointLabel] = datapoint;
}
}
我的解決方案使用Array.map()
。
var temp = ["a","b","c","d","e","f"];
var newchart = chart.map(function (obj) {
var objValKeys = obj.values.map(function (objVal) {
return objVal[0];
});
return {
key: obj.key,
values: temp.map(function (thisval) {
var index = objValKeys.indexOf(thisval);
var actlVal = (index+1) ? obj.values[index][1] : 0;
return [thisval, actlVal];
})
};
});
在我的JSFiddle上檢查
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.