javascript - 根据多个键合并来自两个数组的对象

标签 javascript

下面有两个数组,我想根据两个常用键(“iso3”和“year”)合并它们。每个对象必须两者 相同才能合并。数组的长度不同。

array1 = [{
  "id":24006,
  "iso3":"AFG",
  "country":"Afghanistan",
  "year":2014,
  "value":29.78
},
{
  "id":138806,
  "iso3":"ALB",
  "country":"Albania",
  "year":2013,
  "value":0.6341109715
},
{
  "id":44206,
  "iso3":"DZA",
  "country":"Algeria",
  "year":2014,
  "value":39.928947
}]

array2 = [{
  "indicator_id":21806,
  "footnote_id":64811,
  "iso3":"AFG",
  "year":2014
},
{
  "indicator_id":23806,
  "footnote_id":15711,
  "iso3":"AFG",
  "year":2013
},
{
  "indicator_id":123406,
  "footnote_id":15711,
  "iso3":"ALB",
  "year":2013
},
{
  "indicator_id":101606,
  "footnote_id":48911,
  "iso3":"DZA",
  "year":2013
}];

I saw this answer ,但数组仅基于一个公共(public)键合并。我试图从该代码开始工作,但我没有得到任何结果。感谢您的帮助!

最佳答案

另一种利用 sort() 的方法和 reduce() .

JSFiddle example .

代码:

/* Merges two objects into one. You might add some custom logic here,
   if you need to handle some more complex merges, i.e. if the same
   key appears in merged objects in both arrays */
var merge = function(o1, o2) {
  var result = {};
  for (var a in o1) { result[a] = o1[a]; }
  for (var a in o2) { result[a] = o2[a]; }
  return result;
}

/* Returns 0 if two objects are equal, -1 if first one is 'lower',
   and 1 if it's 'larger'. It's used to sort the arrays. Objects are
   compared using iso3 and year properties only. */
var compareByIsoAndYear = function (o1, o2) {
  if (o1.iso3 === o2.iso3 && o1.year === o2.year) return 0
  else if (o1.year > o2.year) return 1
  else if (o1.year < o2.year) return -1
  else if (o1.iso3 > o2.iso3) return 1;
}

/* Used in reduce */
var mergeTwoObjects = function(initial, current) {
  if (initial.length > 0) {
    var last = initial[initial.length-1];
    if (compareByIsoAndYear(last, current) === 0) {
      initial[initial.length-1] = merge(last, current);
      return initial;
    }
  }
  initial.push(current);
  return initial;
}

/* Take both arrays and concatenate them into one. Then sort them,
   to make sure that objects with the same year and iso3 would appear
   next to each other, and then merge them if needed */
var result = array1.concat(array2)
                   .sort(compareByIsoAndYear)
                   .reduce(mergeTwoObjects, []);

结果:

[{
  "indicator_id": 23806,      /* Found in array2 only, not merged */
  "footnote_id": 15711,
  "iso3": "AFG",
  "year": 2013
}, {
  "id": 138806,               /* This one has been merged */
  "iso3": "ALB",
  "country": "Albania",
  "year": 2013,
  "value": 0.6341109715,
  "indicator_id": 123406,
  "footnote_id": 15711
}, {           
  "indicator_id": 101606,     /* Found in array2 only, not merged */
  "footnote_id": 48911,
  "iso3": "DZA",
  "year": 2013
}, {
  "id": 24006,                /* This one has been merged */
  "iso3": "AFG",
  "country": "Afghanistan",
  "year": 2014,
  "value": 29.78,
  "indicator_id": 21806,
  "footnote_id": 64811
}, {
  "id": 44206,                /* Found in array1 only, not merged */
  "iso3": "DZA",
  "country": "Algeria",
  "year": 2014,
  "value": 39.928947
}]

关于javascript - 根据多个键合并来自两个数组的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34083111/

相关文章:

javascript - 在 return 语句中访问 JS 函数

javascript - 如何将内联 javascript 与 Express/Node.js 中动态生成的内容分开?

javascript - Jquery 将自定义选项卡移动到下一个

javascript - 即使在成功的 promise 回调之后,组件 Prop 也是空的 - Angular Testing

javascript - Sails js - 创建 Assets 的副本

javascript - 如何合并多个 css、js 文件并在 rails 3 中作为一个文件使用?

javascript - 使用jquery数据表我无法在不破坏FixedHead的情况下使单元格colspan = 3

javascript - Webpack 构建时不包含对等依赖项

javascript - 输入字段中每个字母的单独框

javascript - Facebook 照片库查看器