Ces 2 tableaux ont plusieurs objets qui ont le même ID mais des dates différentes

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'}
]

Les données sont dans moment (). unix () pour créer un nombre "facile à comparer"

Je veux créer un troisième tableau qui fusionne les 2 tableaux et crée des objets avec le même identifiant et le dernier objet de date mis à jour.

La sortie devrait être quelque chose comme ça

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

C'est ce que j'ai obtenu jusqu'à présent, si j'ai mis à jour les tableaux, ils sont dupliqués et je n'ai besoin que du dernier objet mis à jour

const third = names.map(t1 => ({...t1, ...lastnames.find(t2 => t2.id === t1.id)})) 
0
Alex Hunter 6 nov. 2020 à 00:46

3 réponses

Meilleure réponse

Je vais supposer que puisque vous avez l'opérateur de diffusion et Array.find dans votre exemple, vous pouvez utiliser ES6, qui inclut for of et Object.values comme vous le voyez ci-dessous.

Un objet et une simple boucle sont utilisés pour réduire le nombre d'itérations. Dans votre exemple, pour chaque élément des noms, vous parcourez les noms de famille pour en trouver un avec le même ID. Non seulement ce n'est pas idéal pour les performances, mais cela ne fonctionne pas car chaque fois que vous trouvez le même élément avec cet ID (le premier avec cet ID dans le tableau).

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);
1
Kevin 5 nov. 2020 à 23:06

J'ai essayé de trouver une solution en utilisant les fonctions de filtrage. Le résultat final contient le format souhaité. Vérifiez-le.

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 ;
}

Voici la dernière sortie:

[…]
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"
1
AntiqTech 6 nov. 2020 à 00:25

L'idée est de regrouper les objets par leurs identifiants, puis de fusionner chaque groupe selon les règles, en maximisant la date pour chaque type d'enregistrement (nom et prénom)

// 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)
1
danh 6 nov. 2020 à 00:03