0

I have this code:

$('#find').click(function(){
    if(first.val() != '' && second.val() != ''){
        $.getJSON(urlPersonSearch + first.val() + "?callback=?", function(json) {
            firstId = (json[0].id != undefined) ? json[0].id : '';
            if(firstId != '') result = grabMovies(firstId);
            var i = result[0].filmography.length;
            while(i--){
                movies[result[0].filmography[i].id] = result[0].filmography[i].name;
            }
        });
        $.getJSON(urlPersonSearch + second.val() + "?callback=?", function(json) {
            secondId = (json[0].id != undefined) ? json[0].id : '';
            if(secondId != '') result = grabMovies(secondId);
            var i = result[0].filmography.length;
            while(i--){
                movies[result[0].filmography[i].id] = result[0].filmography[i].name;
            }
        });

    }

});


function grabMovies(id){
    $.getJSON(urlPersonResult + id + "?callback=?", function(json) {
        return json;
    });
}

Now, what I'm trying to do, is end up with an object with ID and Movie Name as the key/value. Ultimately i'm trying to get an object which contains only the matches between the two json results. Ie.

if the first had a result of

23 = hello, 283 = goodbye,

and the second had a result of

23 = hello, 294 = bye

I would end up with an object of

23 = hello

Has anyone got any advice on how to do this?

benhowdle89
  • 36,900
  • 69
  • 202
  • 331

2 Answers2

0

Let me understand: you are looking for the intersect between two sets. I am not entirely sure what is going on in your code - you have those loops:

movies[result[0].filmography[i].id] = result[0].filmography[i].name;

I assume those are your attempts at finding the intersect. If that is the case, what I would do is to set up two objects, rather than a single 'movies' one, :

$('#find').click(function(){
    var initalMatches = {}; //so this is available to the callbacks below
    if(first.val() != '' && second.val() != ''){
     $.getJSON(urlPersonSearch + first.val() + "?callback=?", function(json) {
        var filmogradphy, i;
        firstId = (json[0].id != undefined) ? json[0].id : '';
        if(firstId != '') result = grabMovies(firstId);
        filmogradphy = result[0].filmogradphy;
        i = filmography.length;
        while(i--){
            initalMatches[filmogradphy[i].id] = filmogradphy[i].name;
        }
    });
    $.getJSON(urlPersonSearch + second.val() + "?callback=?", function(json) {
        var filmogradphy, i, id;
        secondId = (json[0].id != undefined) ? json[0].id : '';
        if(secondId != '') result = grabMovies(secondId);
        filmogradphy = result[0].filmogradphy;
        i = filmography.length;
        while(i--){
            id = filmogradphy[i].id;
            if( "undefined" !== initalMatches[id] ){
                movies[id] = filmography[i].name;
            }
        }
    });

}

});

You can do a fair bit of refactoring here, but this should work :-)

gotofritz
  • 3,341
  • 1
  • 31
  • 47
0

You're looking for an array intersection function. Underscore.js has one. So I was all ready to tell you to use that, but it won't do for this purpose. Look what I tried:

var a = [{23:'hello'},{283:'goodbye'}],
    b = [{23:'hello'},{294:'bye'}];

_.intersection(a,b); // produces []

// investigating further
a.indexOf({23:'hello'}); // -1

The underlying problem here is object equivalency in JavaScript. Note also that

({23:'hello'} === {23:'hello'}); // false
({} === {}) // false

Two JavaScript objects are not equivalent to each other, even if they have the same keys and values. This has to do with the object literal in Javascript calling a constructor under the hood, and thereby reserving a new loctation in memory.

The solution

Underscore appears to have a bug in its _.indexOf method. Other than that, it's a fantastic library and I suggest you use it. I would just extend it with the following:

_.mixin({
    deepIndexOf: function (array, item, isSorted) {
        if (array == null) return -1;
        var i, l;
        if (isSorted) {
          i = _.sortedIndex(array, item);
          return _.isEqual(array[i],item) ? i : -1;
        }
        for (i = 0, l = array.length; i < l; i++) if (i in array && _.isEqual(array[i],item)) return i;
        return -1;
    },
    deepIntersection: function (array) {
        var rest = Array.prototype.slice.call(arguments, 1);
        return _.filter(_.uniq(array), function(item) {
          return _.every(rest, function(other) {
            return _.deepIndexOf(other, item) >= 0;
          });
        });
      }
});

Now, you can run _.deepIntersection(a,b) like so:

var a = [{23:'hello'},{283:'goodbye'}],
    b = [{23:'hello'},{294:'bye'}];

_.deepIntersection(a,b); // produces [{23:'hello'}]
Community
  • 1
  • 1
zetlen
  • 3,609
  • 25
  • 22