web-dev-qa-db-fra.com

Remplacement d'objets dans un tableau

J'ai cet objet javascript:

var arr1 = [{id:'124',name:'qqq'}, 
           {id:'589',name:'www'}, 
           {id:'45',name:'eee'},
           {id:'567',name:'rrr'}]

var arr2 = [{id:'124',name:'ttt'}, 
           {id:'45',name:'yyy'}]

Je dois remplacer des objets dans arr1 par des éléments de arr2 avec le même id .

Alors voici le résultat que je veux obtenir:

var arr1 = [{id:'124',name:'ttt'}, 
           {id:'589',name:'www'}, 
           {id:'45',name:'yyy'},
           {id:'567',name:'rrr'}]

Comment puis-je l'implémenter en utilisant javascript?

14
Michael

Vous pouvez utiliser Array#map avec Array#find .

arr1.map(obj => arr2.find(o => o.id === obj.id) || obj);

var arr1 = [{
    id: '124',
    name: 'qqq'
}, {
    id: '589',
    name: 'www'
}, {
    id: '45',
    name: 'eee'
}, {
    id: '567',
    name: 'rrr'
}];

var arr2 = [{
    id: '124',
    name: 'ttt'
}, {
    id: '45',
    name: 'yyy'
}];

var res = arr1.map(obj => arr2.find(o => o.id === obj.id) || obj);

console.log(res);

Ici, arr2.find(o => o.id === obj.id) renverra l’élément i.e. object de arr2 si id est trouvé dans arr2. Sinon, le même élément dans arr1, c'est-à-dire obj est renvoyé.

37
Tushar

Si vous ne vous souciez pas de l'ordre du tableau, vous voudrez peut-être obtenir la différence entre arr1 et arr2 de id à l'aide de differenceBy () puis utilisez simplement concat () pour ajouter tous les objets mis à jour.

var result = _(arr1).differenceBy(arr2, 'id').concat(arr2).value();

var arr1 = [{
  id: '124',
  name: 'qqq'
}, {
  id: '589',
  name: 'www'
}, {
  id: '45',
  name: 'eee'
}, {
  id: '567',
  name: 'rrr'
}]

var arr2 = [{
  id: '124',
  name: 'ttt'
}, {
  id: '45',
  name: 'yyy'
}];

var result = _(arr1).differenceBy(arr2, 'id').concat(arr2).value();

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.js"></script>

1
ryeballar

Puisque vous utilisez Lodash, vous pouvez utiliser _.map et _.find pour vous assurer que les principaux navigateurs sont pris en charge.

Finalement, je choisirais quelque chose comme:

function mergeById(arr) {
  return {
    with: function(arr2) {
      return _.map(arr, item => {
        return _.find(arr2, obj => obj.id === item.id) || item
      })
    }
  }
}

var result = mergeById([{id:'124',name:'qqq'}, 
           {id:'589',name:'www'}, 
           {id:'45',name:'eee'},
           {id:'567',name:'rrr'}])
    .with([{id:'124',name:'ttt'}, {id:'45',name:'yyy'}])

console.log(result);
<script src="https://raw.githubusercontent.com/lodash/lodash/4.13.1/dist/lodash.js"></script>

1
Dieterg

Je ne fais que soumettre cette réponse parce que des personnes ont exprimé des préoccupations concernant les navigateurs et le maintien de l'ordre des objets. Je reconnais que ce n’est pas le moyen le plus efficace d’atteindre cet objectif. 

Cela dit, j’ai divisé le problème en deux fonctions pour en améliorer la lisibilité.

// The following function is used for each itertion in the function updateObjectsInArr
const newObjInInitialArr = function(initialArr, newObject) {
  let id = newObject.id;
  let newArr = [];
  for (let i = 0; i < initialArr.length; i++) {
    if (id === initialArr[i].id) {
      newArr.Push(newObject);
    } else {
      newArr.Push(initialArr[i]);
    }
  }
  return newArr;
};

const updateObjectsInArr = function(initialArr, newArr) {
    let finalUpdatedArr = initialArr;  
    for (let i = 0; i < newArr.length; i++) {
      finalUpdatedArr = newObjInInitialArr(finalUpdatedArr, newArr[i]);
    }

    return finalUpdatedArr
}

const revisedArr = updateObjectsInArr(arr1, arr2);

jsfiddle

1
spwisner
function getMatch(elem) {
    function action(ele, val) {
        if(ele === val){ 
            elem = arr2[i]; 
        }
    }

    for (var i = 0; i < arr2.length; i++) {
        action(elem.id, Object.values(arr2[i])[0]);
    }
    return elem;
}

var modified = arr1.map(getMatch);
0
user8201502