Linked Lists from JSON

Linked drop down selectors; changing one filters the others

by akbsteam

HTML

<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.1.7/underscore-min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/json2/20110223/json2.js"></script>
<div id="selects">
    <label for="people"><span>Character</span><select id="people"></select></label>
    <label for="locations"><span>Ship</span><select id="locations"></select></label>
    <label for="disciplines"><span>Skills</span><select id="disciplines"></select></label>
</div>

CSS

#selects label { float: left; width: 150px; margin-right: 5px; }
#selects label select,
#selects label span { display: block; width: 150px; }

JavaScript

var jsonData = '{"lists":{"people":{"1":"Jack Sparrow","2":"Captain Barbosa","3":"Davy Jones"},"locations":{"1":"The Black Pearl","2":"The Flying Dutchman"},"disciplines":{"1":"Fighting","2":"Looting","3":"Tentacles","4":"Undead","5":"Rope Tricks"}},"rels":{"people":{"locations":{"1":["1","2"],"2":["1"],"3":["2"]},"disciplines":{"1":["1","2","5"],"2":["1","2","4"],"3":["1","3"]}},"disciplines":{"people":{"1":["1","2","3"],"2":["1","2"],"3":["1","3"],"4":["2"],"5":["1"]},"locations":{"1":["1","2"],"2":["1","2"],"3":["1","2"],"4":["1","2"],"5":["2"],"6":["1","2"]}},"locations":{"people":{"1":["1","2"],"2":["1","3"]},"disciplines":{"1":["1","2","4","5"],"2":["1","2","3","5"]}}}}';

var data = JSON.parse(jsonData);

function intersect_safe(a, b)
{
  var ai=0, bi=0;
  var result = new Array();

  while( ai < a.length && bi < b.length )
  {
     if      (a[ai] < b[bi] ){ ai++; }
     else if (a[ai] > b[bi] ){ bi++; }
     else /* they're equal */
     {
       result.push(a[ai]);
       ai++;
       bi++;
     }
  }

  return result;
}

var changeOpts = function() {
    var currentSelections = {};
    
    $('#selects select').each( function(idx) {
        var id = $(this).attr('id');
        var val = $(this).val() ? $(this).val() : "";
        
        $.each( data.rels[id], function(index, value) {
            if (val == '' || id == index) {
                var dval = [];
                $.each(data.lists[index], function(vi, vv) {
                    dval.push(vi);
                } );
            } else {
                var dval = value[val];
            }
            
            if (typeof(currentSelections[index]) == 'undefined') {
                currentSelections[index] = dval.sort();
            } else {
                currentSelections[index] = intersect_safe(currentSelections[index], dval.sort());
            }
        });
    });
    
    $.each(currentSelections, function(index, value) {
        var current = $('#'+index).val();
        
       ...