繁体   English   中英

如何填充和标准化可变长度数组

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM