合并具有相似项的对象

Merging Objects with Like Terms

我目前正在尝试根据各种特征将数据集组合在一起。我在练习的最后一部分,即:

转这个:

[
  {
    "AU": {
      "iOS": 1
    }
  },
  {
    "US": {
      "iOS": 2
    }
  },
  {
    "CA": {
      "iOS": 1
    }
  },
  {
    "US": {
      "Android": 1
    }
  },
  {
    "DO": {
      "Android": 1
    }
  }
]

进入这个:

[
  {
    "AU": {
      "iOS": 1
    }
  },
  {
    "US": {
      "iOS": 2,
      "Android": 1
    }
  },
  {
    "CA": {
      "iOS": 1
    }
  },
  {
    "DO": {
      "Android": 1
    }
  }
]

换句话说,groupBy CountryCode 并保留各自的 iOS 或 Android 标签。另外,请记住,不允许计算键。 Computed Keys 如有任何帮助,我们将不胜感激。

我不确定你所说的不允许计算键是什么意思,但我已经在 https://jsfiddle.net/ezrajr/z35q9s3h/

上为此设置了一个 jsfiddle

这会将您的数据数组转换为数据对象,这意味着您不必再知道索引。您可以使用字符串访问器符号直接访问数据:

data['US']['iOS'];

或点符号:

data.US.iOS;

两者都适用于访问数据,但通常在您知道密钥时使用点表示法,而在动态设置密钥时使用字符串表示法。

完全香草 JavaScript -

input.forEach(function(item){
    Object.keys(item).forEach(function(country){
        var systems = item[country]
        if (!obj[country]) obj[country] = {}
        Object.keys(systems).forEach(function(system){
            if (!obj[country][system]) obj[country][system] = item[country][system]
            else obj[country][system] += item[country][system]
        })
    })
})

如果您可以使用库(例如下划线或 JQuery),您也可以收紧语法

有了一点 omap 助手和 Object.assign 这是一个非常简单的任务

let input = [
  { "AU": { "iOS": 1 } },
  { "US": { "iOS": 2 } },
  { "CA": { "iOS": 1 } },
  { "US": { "Android": 1 } },
  { "DO": { "Android": 1 } }
]

let omap = (o,f)=>
  Object.keys(o).reduce((acc, k)=>
    Object.assign(acc, { [k]: f(o[k], k, o) }), {})

var output = input.reduce((acc, x) =>
  Object.assign(acc, omap(x, (v, k)=>
    acc[k] === undefined
      ? v
      : Object.assign({}, acc[k], v))), {})

console.log(output)


说明

omap 允许您像映射数组一样映射对象

let omap = (o,f)=>
  Object.keys(o).reduce((acc, k)=>
    Object.assign(acc, { [k]: f(o[k], k, o) }), {})

omap({a:1, b:2, c:3}, x=> x*x)
//=> {a:1, b:3, c:9}

使用omap,我们可以遍历每个输入并将键映射到最终输出对象

// reduce the list of inputs by ...
var output = input.reduce((acc, x) =>
  // assigning to the final output, the omap'd input
  Object.assign(acc, omap(x, (v, k)=>
    // if the final output doesn't have a matching key
    acc[k] === undefined
      // return the input's value
      ? v
      // otherwise return the existing final output merged with the input value
      : Object.assign({}, acc[k], v))), {})

console.log(output)