API Docs for:
Show:

File: yui3-gallery/src/gallery-model-list-difference/js/model-list-difference.js

/**
 * Creates a model list that is the difference of two or more other model lists.
 * @module gallery-model-list-difference
 */
(function (Y) {
    'use strict';

    var _Array = Y.Array,
        _ModelList = Y.ModelList,

        _filter = _Array.filter,
        _indexOf = _Array.indexOf,
        _invoke = _Array.invoke,
        _isString = Y.Lang.isString,
        _reduce = _Array.reduce,
        _reduceFn,
        _unnest = _Array.unnest;

    /**
     * Creates a model list that is the difference of two or more other model
     * lists.  The new model list stays up to date as the source lists change.
     * @method difference
     * @for ModelList
     * @param {Function|Object|String} modelListType Optional.  The first
     * argument determines the type of model list that is created; it may be a
     * constructor function or a string namespace to a constructor function
     * stored on Y. If the first argument is an instance of ModelList, its
     * constructor is used.
     * @param {Object} modelLists 1-n ModelList objects to difference.  Order is
     * important.
     * @return {Object}
     * @static
     */
    Y.ModelList.difference = function () {
        var modelList,
            modelLists = _unnest(arguments),
            modelListType = modelLists.shift(),

            updateModelList = function () {
                return modelList.reset(_reduce(_invoke(modelLists, 'toArray'), 0, _reduceFn));
            };

        if (_isString(modelListType)) {
            modelListType = Y.namespace(modelListType);
        } else if (modelListType instanceof _ModelList) {
            modelLists.unshift(modelListType);
            modelListType = modelListType.constructor;
        }

        modelList = new modelListType();

        _invoke(modelLists, 'after', [
            'add',
            'remove',
            'reset'
        ], updateModelList);

        return updateModelList();
    };
    
    _reduceFn = function (previousArray, currentArray) {
        if (!previousArray) {
            return currentArray;
        }
        
        return _filter(previousArray, function (value) {
            return _indexOf(currentArray, value) === -1;
        });
    };
}(Y));