【问题标题】:Merge not same length arrays of hashes based on key attribute根据键属性合并不同长度的哈希数组
【发布时间】:2016-06-26 23:25:24
【问题描述】:

我想使用 JS、Underscore 或 JQuery 将 2 个哈希数组合并为 1 个新数组。

这两个数组的长度可能不同,合并将基于 id 属性。相同数组之间的哈希值可能不同,例如:

arr1 id's = [1,5]

arr2 id's = [1,2]

这是我的数组:

arr1 = [{
    id: 1
    name: 'fred'
},id: 5
    name: 'alex'
}];

arr2 = [{
    id: 1
    wage: '300'
},{
    id: 2
    wage: '10'
}]

所以基于 id 属性我应该得到以下信息:

arr3 = [{
    id: 1
    name: 'fred'
    wage: '300'
},{
    id: 2
    wage: '10'
},{
    id: 5
    name: 'alex'
}]

我尝试使用Merging/extend javascript object arrays based on join of a key property in each,但如果数组长度不同,它就不起作用。有什么帮助吗?

【问题讨论】:

  • @Mil - 请澄清这是否需要绝对考虑id 索引,例如查看我的答案。您提到它,但在示例数据或问题中不清楚,所以请更新 OP。 stackoverflow.com/help/how-to-ask
  • 要获得答案,请考虑这是明显的重复帖子,请参阅@Oriol 链接。您可以自己回答并接受这一点,尽管在这样做之前将这些答案与此处提供的其他答案进行比较
  • 您好 Daniel,感谢您对此提供的帮助,但 Oriol 的建议并没有解决我的问题(尝试了最佳答案)。我还更新了问题,也许现在更清楚了,我认为@charlietfl 明白了我的意思,因为我在开始时没有很好地解释它 - 索引可能会有所不同

标签: javascript jquery arrays underscore.js


【解决方案1】:

你可以使用Object.assign:

arr1 = [{ id: 1, name: 'fred' }];

arr2 = [
  { id: 1, wage: '300' }, 
  { id: 2, wage: '10' }
];

var result = [];
arr1.concat(arr2)
  .forEach(item =>
    result[item.id] =
    Object.assign({}, result[item.id], item)
  );
result = result.filter(r => r);
console.log(result)

【讨论】:

  • 当我尝试将其转换为咖啡脚本时,由于粗箭头而出现错误,您能解释一下您的答案,以便我可以转换它吗?
  • 这很简单,首先连接所有数组,然后使用 Object.assign 为您完成然后合并。因为 id 是整数,所以我使用 id 作为数组的索引,每次我用当前值更改索引值时都会与项目值合并。考虑应用编辑。
  • @mertezaT 谢谢,这工作得很好,实际上由于索引是基于 int 值的,这可以在字符串上工作吗?例如: id: "1" 而不是 id: 1 因为我需要字符串值而不是整数
【解决方案2】:

编辑

如 cmets 中所述,此解决方案不考虑通过 id 进行的匹配。要查看实际情况,只需将 { id:7, name: 'wilma' } 添加到第一个数组即可。

我将它留在这里,因为从示例数据或描述中不清楚这是 OP 的关键问题,尽管我也有部分错误。但是我会在那里发表评论,如果他说是,我可以编辑或删除它


jQuery.extend()

https://api.jquery.com/jquery.extend/

jQuery.extend([deep], target, object1 [, objectN])

传入该额外参数使其成为深度合并,即递归

https://jsfiddle.net/dabros/q0hhqbmf/

arr1 = [{
    id: 1,
    name: 'fred'
}];

arr2 = [{
    id: 1,
    wage: '300'
},{
    id: 2,
    wage: '10'
}]

arr3 = [];

// Use 2 extends, though $.merge(x,$.extend(y,z)) would work just as well in this case
$.extend(arr3, $.extend(true, arr1, arr2 ));

console.log(arr3);

【讨论】:

  • 当数组长度不同且索引不同时失败。将{ id:7, name: 'wilma' } 添加到第一个数组
  • @charlietfl - 运行该代码,它在 jsfiddle 中完美合并,所有索引以及类似的精确数据
  • 是的,但它只匹配索引...尝试将我刚刚评论的对象添加到第一个数组中。 OP 声明数组长度不匹配
  • 不幸的是,它不够聪明,无法根据共同的属性值进行匹配
  • @charlietfl - 我实际上并没有将其视为 OP 的一部分,并且再次阅读 OP 我仍然没有。我更新了这个,并会在那里评论询问,然后再看
【解决方案3】:

为什么不简单地迭代它们,然后收集到新数组中?

<script src="https://raw.githubusercontent.com/lodash/lodash/4.13.1/dist/lodash.js"></script>
<script>
var arr1 = [
  {
    id: 1,
    name: 'fred'
  },
  {
    id: 5,
    name: 'alex'
  }
];

var arr2 = [
  {
    id: 1,
    wage: '300'
  },
  {
    id: 2,
    wage: '10'
  }
];
  
var a1, a2, arr3 = [], merged = [];
  
// finding intersection and merging
for(a1 = 0; a1 < arr1.length; a1++) {
  for(a2 = 0; a2 < arr2.length; a2++) {
    if(arr1[a1].id === arr2[a2].id) {
      arr3.push(_.extend(arr1[a1], arr2[a2]));
      merged.push(arr1[a1].id);
      break
    }
  }
}

// finding non merged elements and adding
for(a1 = 0; a1 < arr1.length; a1++) {
  if(merged.indexOf(arr1[a1].id) > -1) {
    continue;  
  }
  
  arr3.push(arr1[a1]);
}

// finding non merged elements and adding
for(a2 = 0; a2 < arr2.length; a2++) {
  if(merged.indexOf(arr2[a2].id) > -1) {
    continue; 
  }
  
  arr3.push(arr2[a2]);
}

document.write(JSON.stringify(arr3));
</script>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-13
    • 2018-02-12
    • 2017-12-18
    • 1970-01-01
    • 2019-10-30
    • 1970-01-01
    • 1970-01-01
    • 2019-03-03
    相关资源
    最近更新 更多