如何按特定ID合并和排序2个数组

时间:2018-10-09 16:42:06

标签: javascript typescript ecmascript-6

我想按ID合并这2个数组,并按ID desc对合并的结果数组进行排序。

  • 不想使用任何外部库,例如Lodash或Underscore

  • 首选使用 ES6 并使用更少的代码行

const array1 = [
  {id: "14",  text: "Notice 14"},
  {id: "13",  text: "Notice 13"},
  {id: "12",  text: "Notice 12"},
  {id: "11",  text: "Notice 11"},
  {id: "10",  text: "Notice 10"},
]

const array2 = [ 
  {id: "11",  text: "Notice 11a"},
  {id: "14",  text: "Notice 14a"},
  {id: "12",  text: "Notice 12"},
  {id: "15",  text: "Notice 15"},
]

我想要按ID合并数组,并按ID desc排序:

[
{id: "15",  text: "Notice 15"}
{id: "14",  text: "Notice 14a"}
{id: "13",  text: "Notice 13"}
{id: "12",  text: "Notice 12"}
{id: "11",  text: "Notice 11a"}
{id: "10",  text: "Notice 10"}
]

4 个答案:

答案 0 :(得分:2)

这是filterconcatsort的解决方案(假设array2中的值覆盖array1中的值)。

const array1 = [
  {id: "14",  text: "Notice 14"},
  {id: "13",  text: "Notice 13"},
  {id: "12",  text: "Notice 12"},
  {id: "11",  text: "Notice 11"},
  {id: "10",  text: "Notice 10"}
];

const array2 = [ 
  {id: "11",  text: "Notice 11a"},
  {id: "14",  text: "Notice 14a"},
  {id: "12",  text: "Notice 12"},
  {id: "15",  text: "Notice 15"}
];

const merged = array1
                .filter(e => array2.find(a2e => a2e.id === e.id) === undefined)
                .concat(array2)
                .sort((a, b) => parseInt(b.id) - parseInt(a.id));
console.log(merged);

想法是过滤array1中不在array2中的元素,然后将它们与array2中的所有元素连接起来,因为这是首选数组。

请注意,这并不是很有效,因为我们对最少的代码量感兴趣。我们可以通过创建一组array2的id元素来提高性能,以便用更快的O(1)校验来代替校验array2.find(a2e => a2e.id === e.id) === undefined

答案 1 :(得分:2)

您可以尝试以下方法:

Object
  .values([...array1, ...array2].reduce((acc, item) => ({ ...acc, [item.id]: item }), {}))
  .sort((a, b) => (b.id - a.id))

答案 2 :(得分:0)

任意数量数组的通用解决方案:

LEFT JOIN

打破现状:

考虑到您只希望唯一的id,并且在发生冲突的情况下,首选第二个数组的元素,这是可以做到的:

function mergeArrays(...arrays){
    let obj = {};
    [].concat(...arrays).forEach(item => {
      obj[item.id] = item
    })
    
    return Object.values(obj)
}

进一步解释一下:

1)您将两个数组都转换为一个对象,其中id充当键

2)当两个对象合并时,通过保留第二个对象的值来解决冲突

3)最后,您对第一步进行逆向工程以从对象格式中获取最终的数组。

答案 3 :(得分:0)

使用现代Javascript,您可以使用Map对象来解决此问题。

const array1 = [
    {id: "14",  text: "Notice 14"},
    {id: "13",  text: "Notice 13"},
    {id: "12",  text: "Notice 12"},
    {id: "11",  text: "Notice 11"},
    {id: "10",  text: "Notice 10"}
];

const array2 = [ 
    {id: "11",  text: "Notice 11a"},
    {id: "14",  text: "Notice 14a"},
    {id: "12",  text: "Notice 12"},
    {id: "15",  text: "Notice 15"}
];


function merge(arr1, arr2) {
    // Use a Map to map objects by Id
    const map = new Map();
    arr1.forEach(e => map.set(e.id, e));
    arr2.forEach(e => map.set(e.id, e));

    // Create an empty array and populate it with the map entries
    const result = [];
    map.forEach( (value, key, map) => result.push(value));

    // Sort by ID desc
    result.sort((a, b) => a.id < b.id);
    return result;
}

console.log(merge(array1, array2));

此打印:

[ { id: '15', text: 'Notice 15' },
  { id: '14', text: 'Notice 14a' },
  { id: '13', text: 'Notice 13' },
  { id: '12', text: 'Notice 12' },
  { id: '11', text: 'Notice 11a' },
  { id: '10', text: 'Notice 10' } ]