【问题标题】:Javascript: Adding 0 values to arrays of different sizesJavascript:向不同大小的数组添加0值
【发布时间】:2017-03-23 20:11:39
【问题描述】:

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

我有一个对象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'
    }
] 

如果所述标签的对象不存在,我需要所有“条形”对象的大小相同并且值为 0。如您所见,与“bars”关联的标签键是一个有限列表。我的主要问题是“组”对象的大小以及“条”对象的大小是动态的。带下划线,我用过:

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

提取给我的已知标签列表

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

我现在想把这个数组映射到给我这个输出的 bar 对象:

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'
    }
]

如果有帮助,我必须有偶数条,因为我已经用这些对象 like this example 创建了一个 highcharts 系列。 我希望这是有道理的。任何帮助,将不胜感激。我一直在疯狂地试图弄清楚这一点。

【问题讨论】:

  • _.each 循环遍历groups 的每个元素。使用_.pluck 获取bars 的所有标签,使用_.difference 与已知标签之间的标签获取缺失的标签。然后添加带有这些标签和value: 0的元素。
  • 谢谢!这让我大部分时间都在那里,所以我将其发布为答案

标签: javascript arrays object highcharts underscore.js


【解决方案1】:

这应该可以解决问题:

// 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'
            });
        }
    }
}

【讨论】:

    【解决方案2】:

    这是我为那些偶然发现这个问题的人准备的。

    _.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});
        });
    }); 
    

    【讨论】:

    • 非常好,真正体现了underscore.js的强大。
    【解决方案3】:

    功能性和 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 节省时间!

    第二步,在没有供应商库的情况下完成工作:

    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 就是生命

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-30
    • 2016-05-07
    • 1970-01-01
    • 1970-01-01
    • 2021-11-21
    • 1970-01-01
    • 2017-09-16
    相关资源
    最近更新 更多