繁体   English   中英

如何在Javascript中按id和日期合并2个对象数组?

[英]How to merge 2 array of objects by id and date in Javascript?

这 2 个数组有多个对象,它们具有相同的 ID 但不同的日期

const names= [
{id:'1',name:'a',date:'1604616214'},
{id:'1',name:'Angel',date:'1604616215'},
{id:'2',name:'b',date:'2004616214'},
{id:'2',name:'Karen',date:'2004616215'},
{id:'3',name:'a',date:'3004616220'},
{id:'3',name:'Erik',date:'3004616221'}
]
const lastnames= [
{id:'1',lastname:'a',date:'4004616220'},
{id:'1',lastname:'Ferguson',date:'4004616221'},
{id:'2',lastname:'b',date:'5004616220'},
{id:'2',lastname:'Nixon',date:'5004616221'},
{id:'3',lastname:'a',date:'6004616222'},
{id:'3',lastname:'Richard',date:'6004616223'}
]

数据在 moment().unix() 中创建一个“易于比较”的数字

我想创建一个第三个数组,合并这两个数组并创建具有相同 id 和上次更新日期对象的对象。

输出应该是这样的

const third = [
{id:'1',name:'Angel',lastname:'Ferguson'},
{id:'2',name:'Karen',lastname:'Nixon'},
{id:'3',name:'Erik',lastname:'Richard'}
]

这是我到目前为止得到的,如果我更新了它复制的数组,我只需要最后更新的对象

const third = names.map(t1 => ({...t1, ...lastnames.find(t2 => t2.id === t1.id)})) 

我将假设因为您的示例中有扩展运算符和Array.find ,所以您可以使用 ES6,其中包括for ofObject.values ,如下所示。

对象和简单循环用于减少迭代次数。 在您的示例中,对于名称中的每个元素,您都要遍历姓氏以找到具有相同 ID 的元素。 这不仅对性能不理想,而且不起作用,因为每次您都找到具有该 ID 的相同元素(数组中具有该 ID 的第一个元素)。

const names = [
  { id: "1", name: "a", date: "1604616214" },
  { id: "1", name: "Angel", date: "1604616215" },
  { id: "2", name: "b", date: "2004616214" },
  { id: "2", name: "Karen", date: "2004616215" },
  { id: "3", name: "a", date: "3004616220" },
  { id: "3", name: "Erik", date: "3004616221" },
];
const lastnames = [
  { id: "1", lastname: "a", date: "4004616220" },
  { id: "1", lastname: "Ferguson", date: "4004616221" },
  { id: "2", lastname: "b", date: "5004616220" },
  { id: "2", lastname: "Nixon", date: "5004616221" },
  { id: "3", lastname: "a", date: "6004616222" },
  { id: "3", lastname: "Richard", date: "6004616223" },
];

const profiles = {};

function addToProfiles(arr, profiles) {
  for (let obj of arr) {
    if (obj.id != null) {
      // Inits to an empty object if it's not in the profiles objects
      const profile = profiles[obj.id] || {};
      profiles[obj.id] = { ...profile, ...obj };
    }
  }
}

addToProfiles(names, profiles);
addToProfiles(lastnames, profiles);

const third = Object.values(profiles);

这个想法是按对象的 id 对对象进行分组,然后根据规则合并每个组,最大化每种记录类型(姓名和姓氏)的日期

 // the input data const names= [ {id:'1',name:'a',date:'1604616214'}, {id:'1',name:'Angel',date:'1604616215'}, {id:'2',name:'b',date:'2004616214'}, {id:'2',name:'Karen',date:'2004616215'}, {id:'3',name:'a',date:'3004616220'}, {id:'3',name:'Erik',date:'3004616221'} ] const lastnames= [ {id:'1',lastname:'a',date:'4004616220'}, {id:'1',lastname:'Ferguson',date:'4004616221'}, {id:'2',lastname:'b',date:'5004616220'}, {id:'2',lastname:'Nixon',date:'5004616221'}, {id:'3',lastname:'a',date:'6004616222'}, {id:'3',lastname:'Richard',date:'6004616223'} ] // make one long array let allNames = [...names, ...lastnames] // a simple version of lodash _.groupBy, return an object like this: // { '1': [ { objects with id==1 }, '2': [ ... and so on ] } function groupById(array) { return array.reduce((acc, obj) => { let id = obj.id acc[id] = acc[id] || []; acc[id].push(obj); return acc; }, {}); } // this takes an array of objects and merges according to the OP rule // pick the maximum date name object and maximum date lastname object // this sorts and searches twice, which is fine for small groups function mergeGroup(id, group) { let sorted = group.slice().sort((a, b) => +a.date < +b.date) let name = sorted.find(a => a.name).name let lastname = sorted.find(a => a.lastname).lastname return { id, name, lastname } } // first group, then merge let grouped = groupById(allNames) let ids = Object.keys(grouped) let results = ids.map(id => { return mergeGroup(id, grouped[id]) }) console.log(results)

我试图想出一个使用过滤器功能的解决方案。 最终结果包含您想要的格式。 一探究竟。

const names= [
{id:'1',name:'a',date:'1604616214'},
{id:'1',name:'Angel',date:'1604616215'},
{id:'2',name:'b',date:'2004616214'},
{id:'2',name:'Karen',date:'2004616215'},
{id:'3',name:'a',date:'3004616220'},
{id:'3',name:'Erik',date:'3004616221'}
]
const lastnames= [
{id:'1',lastname:'a',date:'4004616220'},
{id:'1',lastname:'Ferguson',date:'4004616221'},
{id:'2',lastname:'b',date:'5004616220'},
{id:'2',lastname:'Nixon',date:'5004616221'},
{id:'3',lastname:'a',date:'6004616222'},
{id:'3',lastname:'Richard',date:'6004616223'}
]
// filter out last updated objects from both arrays
var lastUpdatednames = names.filter(filterLastUpdate,names);
console.log(lastUpdatednames);
var lastUpdatedsurnames = lastnames.filter(filterLastUpdate,lastnames);
console.log(lastUpdatedsurnames);
// combine the properties of objects from both arrays within filter function.
const third = lastUpdatednames.filter(Combine,lastUpdatedsurnames);
console.log(third);
 
function filterLastUpdate(arrayElement) 
{
    var max =   this.filter( i => arrayElement.id==i.id  ).reduce(
             function(prev, current) 
              {
                return (prev.date > current.date) ? prev : current
               }
           )
        return max.date == arrayElement.date ;
}
function Combine(firstArray) 
{
    
    var subList= this.filter( i => firstArray.id==i.id  );
    //console.log(subList);
    //console.log(subList[0]);
    
    if (subList) 
    { 
       firstArray.lastname = subList[0].lastname;    
       return true;
    }
    return false ;
}

这是最后的输出:

[…]
0: {…}
date: "1604616215"
id: "1"
lastname: "Ferguson"
name: "Angel"
1: {…}
date: "2004616215"
id: "2"
lastname: "Nixon"
name: "Karen"
2: {…}
date: "3004616221"
id: "3"
lastname: "Richard"
name: "Erik"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM