title: Compare two arrays containing objects in order to calculate what changed?
body: <p>Using flat JavaScript or by making use of lodash, what is the simplest way (hoping lodash has a function) which I compare the following arrays and return the value which has changed:</p>
  
  <p><strong>Before</strong></p>
  
  <pre><code>[
    {id: 0, name: 'Bob', age: 27},
    {id: 1, name: 'Frank', age: 32},
    {id: 2, name: 'Joe', age: 38}
  ]
  </code></pre>
  
  <p><strong>After</strong></p>
  
  <pre><code>[
    {id: 0, name: 'Bob', age: 27},
    {id: 1, name: 'Frank', age: 33},
    {id: 2, name: 'Joe', age: 38}
  ]
  </code></pre>
  
  <p>So between before and after, Frank is now age 33, so how can I simply return:</p>
  
  <pre><code>{id: 1, name: 'Frank', age: 33}
  </code></pre>
  
  <p>Or a more desired result:</p>
  
  <pre><code>{id: 1, age: 33}
  </code></pre>
  
  <p><strong>EDIT:</strong></p>
  
  <p>As I got such a nice variation of answers to my question, I decided to test them all on server and client side. Here is what I got after using <a href="http://www.json-generator.com/" rel="nofollow noreferrer">json-generator</a> to generate a json file of 10 000 records:</p>
  
  <p><strong>Node 7.1.0</strong>:</p>
  
  <pre><code>David Domain. (Flat JS filter &amp; some): 3.396
  Result: { id: 1, name: 'Frank', age: 33 }
  Ben Aston (Flat JS nested itteration): 4.359
  Result: { age: 33, id: 1 }
  Gille Q. (Lodash reduce): 21.335
  Result: { id: 1, age: 33 }
  Stasovlas. (Lodash differenceBy): 1.442
  Result: []  
  Vignesh Murugan. (Lodash findWhere): 0
  Result: _.findWhere is not a function
  </code></pre>
  
  <p><strong>Firefox 50.0.2</strong>:</p>
  
  <pre><code>David Domain. (Flat JS filter &amp; some): 6.695
  Result: { id: 1, name: 'Frank', age: 33 }
  Ben Aston (Flat JS nested itteration): 10.594
  Result: { age: 33, id: 1 }
  Gille Q. (Lodash reduce): 40.085
  Result: { id: 1, age: 33 }
  Stasovlas. (Lodash differenceBy): 6.499
  Result: []
  </code></pre>
  
  <p>The interesting thing to note here is that Lodash differenceBy does not seem to work when you're dealing with larger amounts of data, at best i could get this to work with only 3 records before i gave up.</p>
  
  <p>@Vignesh must have worked at one point with Underscore but i'm not going to cover this as things have changed and we now use Lodash.</p>
  
  <p>Here is the code I used to test, used timely to track the amount of time taken to execute a function, then looped 1000 times to get the total time to execute the function 1000 times then divided by 1000 to get the average amount of time taken (in ms) to execute the function:</p>
  
  <pre><code>var fs = require('fs');
  var timely = require('timely');
  var _ = require('lodash');
  
  // Ben Aston
  var ben_aston = function (a, b) {
    return a.reduce((p,c,i)=&gt;{
      var diff = objDiff(c, b[i]);
      diff &amp;&amp; p.push(diff);
      return p;
    }, [])
  }
  function objDiff(a, b) {
    var diff = Object.keys(a).reduce((p,c,i)=&gt;{
      if (a[c] === b[c]) {
        return p;
      }
      p[c] = b[c];
      return p;
    }, {});
    if (!Object.keys(diff).length) {
      return;
    }
    diff.id = a.id;
    return diff;
  }
  var ben_astonT = timely(ben_aston);
  
  
  // Gille Q.
  var gille_q = function (before, after) {
    return _.reduce(before, function(result, value, key) {
      return _.isEqual(value, after[key]) ?
      result : result.concat({id: after[key].id, age: after[key].age});
    }, []);
  }
  var gille_qT = timely(gille_q);
  
  
  // David Domain
  var david_domain = function (before, after) {
    return after.filter( function( p, idx ) {
      return Object.keys(p).some( function( prop ) {
        return p[prop] !== before[idx][prop];
      })
    })
  }
  var david_domainT = timely(david_domain);
  
  
  // Stasovlas
  var stasovlas = function (before, after) {
    return _.differenceBy(after, before, 'age');
  }
  var stasovlasT = timely(stasovlas);
  
  
  // Vignesh Murugan
  var vignesh_murugan = function (before, after) {
    before.forEach((current) =&gt; {
      var after = _.findWhere(after,{id : current.id});
      if(!_.isEqual(after , current)) {
        return _.pick(after,"id","name");
      }
    });
  }
  var vignesh_muruganT = timely(vignesh_murugan);
  
  
  // Load the data
  var before = JSON.parse(fs.readFileSync('./before.json', 'utf8'));
  var after = JSON.parse(fs.readFileSync('./after.json', 'utf8'));
  
  // Open average tracking
  var ben_aston_ave = 0,
      gille_q_ave = 0,
      david_domain_ave = 0,
      stasovlas_ave = 0,
      vignesh_murugan_ave = 0;
  
  // Do test
  for (i = 0; i &lt; 1000; i++) {
    // Ben Aston
    ben_astonT(before, after);
    ben_aston_ave += ben_astonT.time;
  
    // Gille Q.
    gille_qT(before, after);
    gille_q_ave += gille_qT.time;
  
    // David Domain
    david_domainT(before, after);
    david_domain_ave += david_domainT.time;
  
    // Stasovlas
    stasovlasT(before, after);
    stasovlas_ave += stasovlasT.time;
  
    // Vignesh Murugan
    // vignesh_muruganT(before, after);
    // vignesh_murugan_ave += vignesh_muruganT.time;
  }
  
  // Calc averages
  ben_aston_ave = ben_aston_ave / 1000;
  gille_q_ave = gille_q_ave / 1000;
  david_domain_ave = david_domain_ave / 1000;
  stasovlas_ave = stasovlas_ave / 1000;
  vignesh_murugan_ave = vignesh_murugan_ave / 1000;
  
  
  console.log('David Domain. (Flat JS filter &amp; some): '+david_domain_ave);
  console.log('Result: { id: 1, name: \'Frank\', age: 33 }');
  console.log('Ben Aston (Flat JS nested itteration): '+ben_aston_ave);
  console.log('Result: { age: 33, id: 1 }');
  console.log('Gille Q. (Lodash reduce): '+gille_q_ave);
  console.log('Result: { id: 1, age: 33 }');
  console.log('Stasovlas. (Lodash differenceBy): '+stasovlas_ave);
  console.log('Result: []');
  console.log('Vignesh Murugan. (Lodash findWhere): '+vignesh_murugan_ave);
  console.log('Result: _.findWhere is not a function');
  </code></pre>