【问题标题】:How to combine multiple dictionaries in Javascript?如何在Javascript中组合多个字典?
【发布时间】:2019-12-04 02:53:52
【问题描述】:
var dictA = { male: 10, female: 20, unassigned: 30 };
var dictB = { male: 11, female: 21, unassigned: 31 };
var dictC = { male: 12, female: 22, unassigned: 32 };

有没有比多次循环更简单的方法来产生如下结果:

{
    male: [10, 11, 12],
    female: [20, 21, 22],
    unassigned: [30, 31, 32]
}

我不确定“结合”是否是正确的词。

【问题讨论】:

标签: javascript list dictionary


【解决方案1】:

这仍然需要几个循环,但reducefor...in 的组合可能会很好地完成此任务:

var dictA = { male: 10, female: 20, unassigned: 30 };
var dictB = { male: 11, female: 21, unassigned: 31 };
var dictC = { male: 12, female: 22, unassigned: 32 };

const res = [dictA, dictB, dictC].reduce((acc, el) => {
  for (let key in el) {
    acc[key] = [...acc[key] || [], el[key]];
  };
  return acc;
}, {})

console.log(res);

【讨论】:

  • 我很高兴为您解释@JBis 的困惑
  • 它很好用,而且很精简。如果有一个更“可读”的答案,我肯定会接受它——因为归根结底,我宁愿这个而不是多个循环(老实说,这更具可读性)。尽管我对正在发生的一些事情不熟悉 - 我相信我可以通过更多的挖掘找到答案。这是一个快速的响应,谢谢@Nick。
  • @StevenFloyd 没问题!这在技术上是两个循环(reduce 是一个循环,for...in 是一个循环)。话虽这么说,很多其他解决方案都有三个循环,这绝对是多余的
【解决方案2】:

假设dictA 具有所有必要的属性,则此方法有效。它不像@Nicks 那样实用。

const dictA = { male: 10, female: 20, unassigned: 30 };
const dictB = { male: 11, female: 21, unassigned: 31 };
const dictC = { male: 12, female: 22, unassigned: 32 };
    
const obj = {};

Object.keys(dictA).forEach(key => {
   obj[key] = [dictA,dictB,dictC].map(dict => dict[key]);
});

console.log(obj);

【讨论】:

    【解决方案3】:
    var dictA = { male: 10, female: 20, unassigned: 30 };
    var dictB = { male: 11, female: 21, unassigned: 31 };
    var dictC = { male: 12, female: 22, unassigned: 32 };
    
    var input = [dictA, dictB, dictC];
    var output = [];
    input.forEach(function(item) {
      var existing = output.filter(function(v, i) {
        return v.name == item.name;
      });
      if (existing.length) {
        var existingIndex = output.indexOf(existing[0]);
        // output[existingIndex].value = output[existingIndex].value.concat(item.value);
      } else {
        if (typeof item.value == 'string')
          item.value = [item.value];
        output.push(item);
      }
    });
    
    alert(output[0].male);
    

    【讨论】:

      【解决方案4】:

      .reduce().forEach() 也可以这样做

      let result = [dictA, dictB, dictC].reduce((rv, dict) => (
          Object.keys(dict).forEach(key => (
              rv[key] != null ? rv[key].push(dict[key]) : rv[key] = [dict[key]]
          )),
          rv
      ), {});
      

      【讨论】:

        【解决方案5】:

        const addToBucket = (bucket, [k, v], prev = bucket[k] || []) => ({
          ...bucket, [k]: [...prev, v]
        })  
        
        const bucket = list => list.flatMap(Object.entries).reduce(
          (bucket, entry) => addToBucket(bucket, entry), {}
        )
        
        // ---------------------------------------------------------- //
        console.log(bucket([
          { male: 10, female: 20, unassigned: 30 },
          { male: 11, female: 21, unassigned: 31 },
          { male: 12, female: 22, unassigned: 32 },
        ]))

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-04-22
          • 1970-01-01
          • 2017-09-12
          • 2012-05-20
          • 1970-01-01
          • 1970-01-01
          • 2020-07-29
          相关资源
          最近更新 更多