Chained select box fiddle
Chained select box and an Array.prototype function fiddle
I had a chained select box and an Array.prototype function to combine two arrays into an associated array.They are for different use and unrelated. But when they are put together in the script, it gives me undefined is not a function pointing to this part this.forEach as the source of error. I ended up replacing the Array.prototype function with this one (Example fiddle):
function associate(keys, values){
    return keys.reduce(function (previous, key, index) {
        previous[key] = values[index];
        return previous
    }, {})
} 
I'm just curious why there is a conflict between the chained select box and the Array.prototype function?
Here's the code:
$(document).ready(function(){
var data = [
  {
    "bigcat": "Sport",
    "cat": "mainstream",
    "choice": "football"
  },
  {
    "bigcat": "Sport",
    "cat": "mainstream",
    "choice": "basketball"
  },
  {
    "bigcat": "Sport",
    "cat": "niche",
    "choice": "MMA"
  },
  {
    "bigcat": "Sport",
    "cat": "niche",
    "choice": "wrestling"
  }
]
var $select = $('select');var $option="";
$.each(data, function (index, i) {
  $option = $("<option/>").attr("value", i.choice).text(i.bigcat + "@" +( i.cat || "") +"@" +  i.choice);
  $select.append($option); 
});
$select.dynamicDropdown({"delimiter":"@"});
});
Array.prototype.associate = function (keys) {
  var result = {};
  this.forEach(function (el, i) {
    result[keys[i]] = el;
  });
  return result;
};
var animals = ['Cow', 'Pig', 'Dog', 'Cat'];
var sounds = ['Moo', 'Oink', 'Woof', 'Miao'];
console.dir(sounds.associate(animals));
Dynamic Drop down box Script
(function($) {
  $.dynamicDropdown = {
    /**
     * Escape quotation marks and slashes
     * @param {String} String to format
     * @return {String}
     */
    escapeQuotes : function(str) {
      return str.replace(/([""\\])/g, "\\$1");
    },
    /**
     * Build a <select> box from options
     * @param {Array} Options
     * @return {jQuery}
     */
    buildSelectDropdown : function(options) {
      var select = $(document.createElement("select"));
      var option = null;
      // Add options
      for (var i in options) {
        option = $(document.createElement("option"))
          .val($.isArray(options[i]) ? i : options[i])
          .html(i)
          .appendTo(select);
      }
      return select;
    }
  };
  $.fn.dynamicDropdown = function(options) {
    var settings = {
      "delimiter" : " ?",
      "className" : "dynamic-dropdown"
    };
    $.extend(settings, options);
    return $(this).each(function() {
      /**
       * Main dropdown (this)
       * @type jQuery
       */
      var mainDropdown = $(this);
      /**
       * Position of initial value of main dropdown
       * @type Array
       */
      var initialPosition = [];
      /**
       * Main array of all elements
       * @type Array
       */
      var data = [];
      /**
       * Array of all <select> boxes
       * @type Array
       */
      var selectElements = [];
      /**
       * Flag denoting whether the dropdown has been initialized
       * @type Boolean
       */
      var isInitialized = false;
      /**
       * Prepare a dropdown for use as a dynamic dropdown
       * @param {jQuery|string} Dropdown
       * @param {jQuery|HTMLElement} Sibling
       * @param {Number} Level
       * @param {Number} Position in the main array
       * @return {jQuery}
       */
      var prepareDropdown = function(dropdown, sibling, level, position) {
        return $(dropdown)
          .addClass(settings.className)
          .data("level", level)
          .data("position", position)
          .insertAfter(sibling)
          .each(buildDynamicDropdown)
          .change(buildDynamicDropdown);
      };
      /**
       * Initialize the dynamic dropdown <select> boxes
       * @return {jQuery}
       */
      var buildDynamicDropdown = function() {
        var level = $(this).data("level") + 1;
        var position = "";
        // Get the position in the main data array
        if (!isInitialized) {
          for (var i = 0; i < level; i++) {
            position += "[\"" + initialPosition[i] + "\"]";
          }
        } else {
          position = $(this).data("position") + "[\"" + $.dynamicDropdown.escapeQuotes($(this).val()) + "\"]";
          // Remove old <select> boxes
          for (var i = selectElements.length; i > level; i--) {
            selectElements.pop().remove();
          }
        }
        var selectionOptions = eval("data" + position);
        if ($.isArray(selectionOptions)) {
          // Build the next dropdown
          selectElements.push($.dynamicDropdown.buildSelectDropdown(selectionOptions));
          if (!isInitialized) {
            $(this).val(initialPosition[level - 1]);
          }
          prepareDropdown(selectElements[selectElements.length - 1], this, level, position);
        } else if (!isInitialized) {
          // Set the final value
          $("option:contains('" + initialPosition[level - 1] + "')", selectElements[selectElements.length - 1]).attr("selected", "selected");
          isInitialized = true;
        } else {
          // Set the value
          mainDropdown.val($(this).val());
        }
        return $(this);
      };
      // Build the dynamic dropdown data
      mainDropdown.children().each(function() {
        var parts = $(this).html().split(settings.delimiter);
        var name = "data";
        var value = null;
        // Set the initial position
        if ($(this).is(":selected")) {
          initialPosition = parts;
        }
        // Build the position of the current item
        for (var i in parts) {
if(typeof parts[i] != "string") continue;
          name += "[\"" + $.dynamicDropdown.escapeQuotes(parts[i]) + "\"]";
          value = eval(name);
          if (!value) {
            // Set the level to have an empty array to be filled
            eval(name + " = [];");
          } else if (!$.isArray(value)) {
            // Add data to the array
            eval(name + " = [" + eval(name) + "];");
          }
        }
        // Set the final index to have the value
        eval(name + " = \"" + $(this).val() + "\";");
      });
      // Build the dynamic dropdown
      selectElements[0] = $.dynamicDropdown.buildSelectDropdown(data);
      prepareDropdown(selectElements[0], this, 0, "");
    }).hide();
  };
})(jQuery);
(function($) 
{
    $.fn.dynamicDropdown = function(options) {
        var settings = {
            "delimiter" : " » ",
            "className" : "",
            "levels"    : [ 
                {'markup':"{dd}",'class':false,'id':false,'disabled':false},
                {'markup':"{dd}"}
            ]
        };
        $.extend(settings, options);
        return $(this).each(function() {
            //the original dropdown element
            var mainDropdown = $(this);
            var defaultSelection = false;
            var levels = {};
            //insert dropdown into markup, and finally place it in the DOM, attaching events, etc.
            var insertSelectDropdown = function(dd, level, sibling, position){
                var markup = settings.levels[level] && settings.levels[level].markup ? settings.levels[level].markup : '{dd}';
                //to support markup both placing the dropdown within a container and without a container, 
                //its necessary to use a little silly dom magic
                var container = $('<div>'+settings.levels[level].markup.replace('{dd}',$('<div></div>').append(dd.addClass('ddlevel-'+level)).html())+'</div>').children()['insert'+position](sibling);
                var select = container.parent().find('select.ddlevel-'+level).removeClass('ddlevel-'+level);
                if (settings.levels[level]['class']){
                    select.addClass(settings.levels[level]['class']);
                }
                if (settings.levels[level].id){
                    select.attr('id',settings.levels[level].id);
                }
                if (settings.levels[level].disabled){
                    select.prop('disabled','disabled');
                }
                return select.data('level',level).data('container',container).data('levels',dd.data('levels')).change(updateDropdowns);
            }
            //produce markup for select element
            var buildSelectDropdown = function(options, selected) {
                var select = $('<select></select>').data('levels',options);
                // Add options
                $.each(options,function(index,value){
                    var option = $('<option></option>').html(index);
                    if (typeof(value) != 'object'){
                        option.val(value);
                    }
                    if (selected && index == selected){
                        option.attr('selected','selected');
                    }
                    select.append(option);
                });
                return select;
            };
            //the event function that runs each time a select input value changes
            var updateDropdowns = function(){
                var current = $(this).children(':selected').html();
                var options = $(this).data('levels')[current];
                //a non-object means this is the end of the line, set the value
                if (typeof(options) != 'object'){
                    mainDropdown.val($(this).val());
                }
                else {
                    //remove any dds after the one that just changed
                    var dd = $(this);
                    while (dd.data('next')){
                        dd = dd.data('next');
                        dd.data('container').detach();
                    }
                    var level = $(this).data('level') + 1;
                    //add new dds
                    $(this).data('next',insertSelectDropdown(buildSelectDropdown(options, defaultSelection[level]), level, $(this).data('container').last(), 'After').change());
                }
            };
            //build levels from initial dropdown
            mainDropdown.children().each(function() {
                var options = $(this).html().split(settings.delimiter); 
                if ($(this).is(":selected")){
                    defaultSelection = options;
                }       
                var level = levels;
                for (var i=0; i < options.length; i++) {
                    if (!level[options[i]]){
                        //either an option is an object pointing to other objects/values,
                        //or some other type value, indicating that the user has made a selection
                        level[options[i]] = ((i+1)==options.length) ? $(this).val() : {};
                    }
                    level = level[options[i]];
                }
            });
            //if no default selection, use first value
            if (!defaultSelection){
                defaultSelection = mainDropdown.children().first().html().split(settings.delimiter);
            }
            insertSelectDropdown(buildSelectDropdown(levels,defaultSelection[0]), 0, mainDropdown, 'Before').change();
        //hide initial dropdown
        }).hide();
    };
})(jQuery);
 
    