1
votes

Comparer deux objets pour créer un nouvel objet

J'ai deux tableaux d'objets. Ce que je veux faire, c'est:

  1. Comparez deux objets
  2. Lorsque la clé (nom) et sa valeur sont identiques, ajoutez ces données à data_1
  3. Créez un troisième objet (data_3) avec des données complètes.

Deux objets que je veux comparer:

data_3 = [
           {id: "A1", name: "Jack", age: 20}
           {id: "A2", name: "Mike", age: 30},
           {id: "A3", name: "Kelly", age: 25}}
         ]

Nouvel objet avec des données complètes:

data_1 = [
           {name: "Mike", age: 30},
           {name: "Kelly", age: 25},
           {id: "A1", name: "Jack", age: 20}
         ]

data_2 = [
           {id: "A2", name: "Mike"},
           {id: "A3", name: "Kelly"}
         ]

J'ai essayé d'utiliser Array.prototype.forEach () mais ça ne va pas bien ... :(


3 commentaires

Ce serait plus facile si vous changiez l'un des tableaux en un objet dont la clé est le nom.


Votre question est un peu contradictoire. En fonction des conditions que vous avez définies, comment obtiendriez-vous cette ligne id: "A1", nom: "Jack", age: 20 ? Il n'y a pas de clé correspondante pour cela dans l'autre tableau


Je veux comparer nom . Par exemple, il y a name: "Mike" dans data_1, et il y a aussi name: "Mike" dans data_2. Donc, dans ce cas, je veux prendre {id: "A2", name: "Mike"} de data_2 et ajouter à {name: "Mike", age: 30} dans data_1 pour créer {id: "A2", nom: "Mike", âge: 30} . Désolé, je suis si nouveau dans ce monde ... est-ce que cela a du sens?


4 Réponses :


1
votes

Vous pouvez concat les deux tableaux et que le réduire en fonction des noms.

let data_1 = [{name: "Mike", age: 30},{name: "Kelly", age: 25},{id: "A1", name: "Jack", age: 20}]
let data_2 = [{id: "A2", name: "Mike"},{id: "A3", name: "Kelly"}]

let merged = [...data_1,...data_2].reduce((op,{name,id,age}) => {
  if( op[name] ){
    op[name].id = id != undefined ? id : op[name].id
  } else {
    op[name] = {
      name,
      age,
      id: id!=undefined ? id : 'Not available'
    }
  }
  return op
},{})

console.log(Object.values(merged))


1 commentaires

Je n'ai pas pensé à concat ... !! Merci!



1
votes

Vous pouvez utiliser map , certains et find comme ceci, avec une déstructuration pour simplifier les choses:

const data_1 = [{
    name: "Mike",
    age: 30
  },
  {
    name: "Kelly",
    age: 25
  },
  {
    id: "A1",
    name: "Jack",
    age: 20
  }
];

const data_2 = [{
    id: "A2",
    name: "Mike"
  },
  {
    id: "A3",
    name: "Kelly"
  }
];

function combineArrays(arr1, arr2) {
  let result = arr1.map(obj => {
    if (obj.name && obj.age && obj.id) return obj;
    if (arr2.some(({ id, name }) => obj.name == name)) {
      let { id, name } = arr2.find(e => obj.name == e.name);
      return {
        id,
        name,
        age: obj.age
      };
    }
  });
  return result.sort((a, b) => +a.id[1] - +b.id[1]);
}

const data_3 = combineArrays(data_1, data_2);

console.log(data_3);


2 commentaires

Merci beaucoup! C'est très simple et clair ... travailler exactement comme je le voulais !!


Aucun problème @Kiki, je suis heureux d'avoir aidé.



1
votes

Si vous voulez plus moins de code. Vous pouvez utiliser lodash

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
data_1 = [{name: "Mike", age: 30},{name: "Kelly", age: 25},{id: "A1", name: "Jack", age: 20}]
data_2 = [{id: "A2", name: "Mike"},{id: "A3", name: "Kelly"}]

let d1 = _.keyBy(data_1, 'name')
let d2 = _.keyBy(data_2, 'name')
let rs = _.merge(d1, d2)
console.log(_.values(rs))


1 commentaires

Je ne connaissais pas cette bibliothèque! Le code a l'air si propre ... merci pour l'info!



0
votes

data_1 = [{
    name: "Mike",
    age: 30
  },
  {
  	id:"A4",
    name: "Simon",
    age: 25
  },
  {
    id: "A1",
    name: "Jack",
    age: 20
  }
]

data_2 = [{
    id: "A2",
    name: "Mike"
  },
  {
    id: "A3",
    name: "Kelly"
  }
]
data_3 = [];
for (let i = 0, imax = data_1.length; i < imax; i++) {
  if (typeof data_2[i] != "undefined") { // this will check undefined index of different range
    if (typeof data_2[i].name != "undefined") { // this will check name attribute assume some times only get id and age prob if not remove this 
      if (data_1[i].name == data_2[i].name) { // this will compare 2 name if same merge it into 1 object
        let obj = extend(data_2[i], data_1[i]);
        data_3.push(obj) // then push to the array merged object
      }else{ // this else will push if name does not match but some id name bla bla..
      data_3.push(data_1[i]);
      }
    }
  } else { // this else will push if data_1 array longer than data_2 indexes values goes in here
    data_3.push(data_1[i]);
  }

}


// this function extend 2 object got
function extend(obj, src) {
  for (var key in src) {
    if (src.hasOwnProperty(key)) obj[key] = src[key];
  }
  return obj;
}
console.log(data_3)


0 commentaires