Javascript:为不同大小的数组添加0值

Javascript: Adding 0 values to arrays of different sizes

本文关键字:数组 添加 Javascript      更新时间:2023-09-26

解释起来很复杂,所以我会尽量明确。

我有一个对象data,它是一个对象数组,包含一个对象数组和一个字符串:

var groups = [
    { 
        bars: [
            {label: 'a', value: 28},
            {label: 'c', value: 16}
        ],
        string: 'one'
    },
    {
        bars: [
            {label: 'a', value: 3},
            {label: 'b', value: 17},
            {label: 'c', value: 24}
        ],
        string: 'two'
    },
    {
        bars: [
            {label: 'a', value: 12},
            {label: 'd', value: 7},
            {label: 'e', value: 36}
        ],
        string: 'three'
    },
    {
        bars: [
            {label: 'c', value: 32},
            {label: 'e', value: 2}
        ],
        string: 'four'
    }
] 

我需要所有"bars"对象具有相同的大小,并且如果所述标签的对象不存在,则具有0值。如您所见,与"bars"相关联的标签键是一个有限列表。这里我的主要问题是"groups"对象的大小以及"bars"对象的大小是动态的。对于下划线,我使用了:

var labelNames = _.uniq(_.flatten
    (_.map(data.groups,function(groups) {
    return _.pluck(groups.bars, 'label');
})));

提取已知标签列表,得到

['a', 'b', 'c', 'd', 'e']

我现在想把这个数组映射到bars对象,得到这样的输出:

var groups = [
    { 
        bars: [
            {label: 'a', value: 28},
            {label: 'b', value: 0},
            {label: 'c', value: 16},
            {label: 'd', value: 0},
            {label: 'e', value: 0}
        ],
        string: 'one'
    },
    {
        bars: [
            {label: 'a', value: 3},
            {label: 'b', value: 17},
            {label: 'c', value: 24},
            {label: 'd', value: 0},
            {label: 'e', value: 0}
        ],
        string: 'two'
    },
    {
        bars: [
            {label: 'a', value: 12},
            {label: 'b', value: 0},
            {label: 'c', value: 0},
            {label: 'd', value: 7},
            {label: 'e', value: 36}
        ],
        string: 'three'
    },
    {
        bars: [
            {label: 'a', value: 0},
            {label: 'b', value: 0},
            {label: 'c', value: 32},
            {label: 'd', value: 0},
            {label: 'e', value: 2}
        ],
        string: 'four'
    }
]

如果有用的话,我必须有偶数条,因为我已经用这些对象创建了一个highcharts系列,就像这个例子一样。我希望这能说得通。任何帮助都会很感激。我想弄明白这事都快疯了。

这是我为那些偶然发现的人所做的。

_.each(data.groups, function(group) {
    var currentValues = _.pluck(group.bars, 'label');
    var zeroValues = _.difference(labelNames, currentValues);
    _.each(zeroValues, function(newLabel) {
        group.bars.push({label: newLabel, value: 0});
    });
}); 

这应该能奏效:

// First, iterate over each group
for (var i = 0; i < groups.length; i++) {
    var bars = groups[i].bars;
    // Second, iterate over each of the previously collected labels, e.g. var labels = ['a', 'b', 'c', 'd', 'e']
    for (var j = 0; j < labels.length; j++) {
        // Assume label does not exist, until proven otherwise
        var labelDoesNotExist = true;
        // Third, iterate over the bars' existing labels
        for (var k = 0; k < bars.length; k++) {
            var label = bars[k].label;
            // Check if the label matches the current iteration of pre-collected labels
            if (label == labels[j]) {
                labelDoesNotExist = false;
            }
        }
        // If no existing label matches any of the pre-collected labels, then create a new label with value of 0
        if (labelDoesNotExist) {
            bars.push({
                'label': labels[j],
                'value': '0'
            });
        }
    }
}

一个功能和EcmaScript6的替代品:

首先,获取标签:['a', 'b ', 'c',…]

let labels = groups
  .reduce((res, item) => 
    [...res, ...item.bars.map(b => b.label)], 
  [])
  .filter((value, index, self) => 
    self.indexOf(value) === index
  )
  .sort()

用reduce和concat节省时间!

第二步,让job不需要厂商的库:

let newgroups = groups.map(item  => 
  Object.assign({}, item, {bars : [
    ...item.bars, 
    ...labels.filter(l => 
        !item.bars.some(b => b.label == l)
      )
      .map(l => ({label:l, value:0}))
  ].sort((a, b) => a.label < b.label ? -1:1)})
);

最终的sort是可选的,但条形物品可以更好地使用它。

工作在Chrome和实际引擎没有转译。ES6 is life