Question

If I was to say "What is the difference between these arrays? ['a'] and ['a', 'b']?" you would say 'b' right?

I was wondering what the reason is for underscore to not have an bidirectional diff by default? And how would you combine the other methods to achieve this?

var a = ['js-email'],
    b = ['js-email', 'form-group'],
    c = _.difference(a, b), // result: []
    d = _.difference(b, a); // result: ["form-group"]

http://jsfiddle.net/GH59u/1/

To clarify I would like the difference to always equal ['form-group'] regardless of what order the arrays are passed.

Was it helpful?

Solution

You can just combine the differences between the two items in two directions.

function absDifference(first, second) {
    return _.union(_.difference(first, second), _.difference(second, first));
}

console.assert(absDifference(["a", "b"], ["a", "c"]).toString() == "b,c");
var a = ["js-email"], b = ["js-email", "form-group"];
console.assert(absDifference(a, b).toString() == "form-group");

If you want this to be available as part of _ library itself, throughout your project, then you can make use of _.mixin like this

_.mixin({
    absDifference: function(first, second) {
        return _.union(_.difference(first, second), _.difference(second, first));
    }
});

and then

console.assert(_.absDifference(["a", "b"], ["a", "c"]).toString() == "b,c");
var a = ["js-email"],
    b = ["js-email", "form-group"];
console.assert(_.absDifference(a, b).toString() == "form-group");

OTHER TIPS

.difference, just like PHP's array_diff function and others like it, returns all items that are in the first array, that do not appear in any other arrays passed to it.

This means that "the things in a that aren't in b" is very different to "the things in b that aren't in a" and for good reason - this is expected behaviour.

If you want what is essentially a bidirectional difference, you will need to run the function both ways, then strip out duplicates in the result.

_.differenceaccepts a variable number of arrays as argument:

Similar to without, but returns the values from array that are not present in the other arrays

So it allows just one-directional operation by design.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top