0

I'm using underscore.js on my project and i want to compare two arrays but only their intersection by one field.

The first array :

[{item: myObject1, label: myObject1.name, ticked: true, disabled: false}]

the second array :

[{item: myObject1, label: myObject1.name, ticked: false, disabled: false}, 
{item: myObject2, label: myObject2.name, ticked: true, disabled: false}]

I want to return intersection of these arrays by myObject.id and compare it :

  1. intersection :

    {item: myObject1, label: myObject1.name, ticked: true, disabled: false}
    

and

{item: myObject1, label: myObject1.name, ticked: false, disabled: false}

because myObject1 is the intersection (myObject1.id == myObject1.id).

  1. these items are not equals because the first element is ticked and the second no... so, return false;

I don't see how can i do that with underscore.js.

EDIT:

with only isEqual function, i can do that (i use AngularJS):

isIOEquals: function(inputs, outputs){
        var editedInputs = [];
        var editedOutputs = [];
        angular.forEach(outputs, function(outputItem){
            angular.forEach(inputs, function(inputItem){
                if(_.isEqual(inputItem.item.id, outputItem.item.id)){
                    editedInputs.push(inputItem);
                    editedOutputs.push(outputItem);
                }
            });
        });

        return _.isEqual(editedInputs, editedOutputs);
    }
slim
  • 447
  • 2
  • 10
  • 27
  • possible duplicate of [How to use underscore's "intersection" on objects?](http://stackoverflow.com/questions/8672383/how-to-use-underscores-intersection-on-objects) – Vladu Ionut Mar 01 '15 at 14:56
  • Just to be clear, you want the intersection, but you want it to ignore everything but the item attribute? – demux Mar 01 '15 at 15:02
  • Yes. For the intersection, i want to ignore everything except the object id (myObject.id). After that, i want to compare the elements of the intersection. – slim Mar 01 '15 at 15:06
  • Ok, and all these objects are in the same array? – demux Mar 01 '15 at 15:09
  • wich objets ? there are two arrays at the begining ("the first" and "the second" in the question). – slim Mar 01 '15 at 15:12
  • Yes, sorry, poorly worded on my behalf. – demux Mar 01 '15 at 15:12
  • and the result of intersection is two objects because i have to compare it. – slim Mar 01 '15 at 15:13
  • 1
    Do you mean `.item.id`? There are no `myObject`s in your arrays. – Bergi Mar 01 '15 at 15:15
  • myObject1 is an object... : {id: 4, field1: 'myfield'} – slim Mar 01 '15 at 15:24

1 Answers1

1

I believe this will do the job.

function myIntersection() {
    var objectLists = [].slice.call(arguments),
        objMapper = objectLists.pop();

    var flatLists = objectLists.map(function(lst) {
        return lst.map(objMapper);
    });

    // There will be duplicates in this list, but maybe that's the desired
    // behaviour, so I'll leave it to you to sort that out.
    var mergedObjectLists = _.flatten(objectLists);

    var intersectingValues = _.intersection.apply(null, flatLists);
    return mergedObjectLists.filter(function(obj) {
        return intersectingValues.indexOf(objMapper(obj)) !== -1
    });
}

myIntersection(list1, list2, function(obj) {return obj.item.id});

I'd love to see other approaches.

demux
  • 4,544
  • 2
  • 32
  • 56