Search code examples
javascriptlodash

Lodash DifferenceBy not behaving as expected


I've been trying to use lodash (4.13.1) _.differenceBy and I must be missing something.

I've got a fiddle here: http://jsfiddle.net/cmwye4z1/2/

Here's the javascript:

$scope.files_a = [
    {'name': 'file1.wav', 'size': 989010, 'duration': 44.953, 'temp': 1},
    {'name': 'file2.wav', 'size': 326984, 'duration': 14.860, 'temp': 1},
    {'name': 'file3.wav', 'size': 584723, 'duration': 28.583, 'temp': 1},
    {'name': 'file4.wav', 'size': 483829, 'duration': 22.859, 'temp': 1},
    {'name': 'file5.wav', 'size': 283949, 'duration': 9.495, 'temp': 1},
    {'name': 'file6.wav', 'size': 839372, 'duration': 38.584, 'temp': 1},
    {'name': 'file7.wav', 'size': 784949, 'duration': 29.594, 'temp': 1}
];

$scope.files_b = [
    {'name': 'file8.wav', 'size': 989010, 'duration': 44.953, 'temp': 'auto'},
    {'name': 'file2.wav', 'size': 326984, 'duration': 14.860, 'temp': 1}
];

$scope.differenceBy = _.differenceBy($scope.files_a, $scope.files_b, ['name', 'size', 'duration']);

And what I expected was:

$scope.differenceBy = [
    {'name': 'file1.wav', 'size': 989010, 'duration': 44.953, 'temp': 1},
    {'name': 'file3.wav', 'size': 584723, 'duration': 28.583, 'temp': 1},
    {'name': 'file4.wav', 'size': 483829, 'duration': 22.859, 'temp': 1},
    {'name': 'file5.wav', 'size': 283949, 'duration': 9.495, 'temp': 1},
    {'name': 'file6.wav', 'size': 839372, 'duration': 38.584, 'temp': 1},
    {'name': 'file7.wav', 'size': 784949, 'duration': 29.594, 'temp': 1}
];

With file2.wav removed, but what I get is just $scope.files_a.

If I remove the brackets, then I get file3, file4, file5, file6 and file7.

If I understand the documentation correctly, the iteratee can be an array, but maybe I'm mistaken? Could someone please set me straight?


Solution

  • My comment, in other words, is to either wait for an answer from someone smarter about how differenceBy really works with an array argument, or use...

    $scope.differenceBy = _.differenceBy($scope.files_a, $scope.files_b, function(obj) {
        return obj.name + obj.size;
    });
    

    which appears to work correctly in your fiddle.