multiplex/multiplex.js

View on GitHub
src/lib/linq/_linq.js

Summary

Maintainability
D
1 day
Test Coverage
import mixin from '../utils/mixin';
import isFunction from '../utils/is-function';

import List from '../collections/list';
import Lookup from '../collections/lookup';
import EmptyIterable from '../iteration/iterable-empty';
import OrderedIterable from '../collections/ordered-iterable';

import buffer from '../utils/buffer';
import range from './range';
import repeat from './repeat';
import aggregate from './aggregate';
import all from './all';
import any from './any';
import average from './average';
import concat from './concat';
import contains from './contains';
import count from '../utils/count';
import defaultIfEmpty from './default-if-empty';
import distinct from './distinct';
import elementAt from './element-at';
import exceptIntersect from './except-intersect';
import first from './first';
import firstOrDefault from './first-or-default';
import forEach from './for-each';
import groupBy from './group-by';
import groupJoin from './group-join';
import join from './join';
import last from './last';
import lastOrDefault from './last-or-default';
import minMax from './min-max';
import ofType from './of-type';
import reverse from './reverse';
import select from './select';
import selectMany from './select-many';
import sequenceEqual from './sequence-equal';
import single from './single';
import singleOrDefault from './single-or-default';
import skip from './skip';
import skipWhile from './skip-while';
import sum from './sum';
import take from './take';
import takeWhile from './take-while';
import toDictionary from './to-dictionary';
import union from './union';
import where from './where';
import zip from './zip';

export default function linq(iterable) {
    mixin(iterable, {

        /**
        * Returns an empty Iterable.
        * @returns {Iterable}
        */
        empty: function () {
            return new EmptyIterable();
        },

        /**
        * Generates a sequence of integral numbers within a specified range.
        * @param {Number} start The value of the first integer in the sequence.
        * @param {Number} count The number of sequential integers to generate.
        * @returns {Iterable}
        */
        range: range,

        /**
        * Generates a sequence that contains one repeated value.
        * @param {Object} element The value to be repeated.
        * @param {Number} count The number of times to repeat the value in the generated sequence.
        * @returns {Iterable}
        */
        repeat: repeat
    });

    mixin(iterable.prototype, {

        /**
        * Applies an accumulator function over a sequence.
        * @param {Object} seed The initial accumulator value.
        * @param {Function} func An accumulator function to be invoked on each element. eg. function(accumulate, item)
        * @param {Function} resultSelector A function to transform the final accumulator value into the result value. eg. function(accumulate)
        * @returns {Object}
        */
        aggregate: function (seed, func, resultSelector) {
            return aggregate(this, seed, func, resultSelector);
        },

        /**
        * Determines whether all elements of a sequence satisfy a condition.
        * Returns true if every element of the source sequence passes the test in the specified predicate, or if the sequence is empty; otherwise, false.
        * @param {Function} predicate A function to test each element for a condition. eg. function(item).
        * @returns {Boolean}
        */
        all: function (predicate) {
            return all(this, predicate);
        },

        /**
        * Determines whether a sequence contains any elements.
        * Returns true if any elements in the source sequence contains any elements or pass the test in the specified predicate; otherwise, false.
        * @param {Function=} predicate A function to test each element for a condition. eg. function(item).
        * @returns {Boolean}
        */
        any: function (predicate) {
            return any(this, predicate);
        },

        /**
        * Computes the average of a sequence of numeric values.
        * @param {Function=} selector A transform function to apply to each element. eg.function(item).
        * @returns {Number}
        */
        average: function (selector) {
            return average(this, selector);
        },

        /**
        * Concatenates two sequences.
        * @param {Iterable} second The sequence to concatenate to current sequence.
        * @returns {Iterable}
        */
        concat: function (second) {
            return concat(this, second);
        },

        /**
        * Determines whether a sequence contains a specified element by using an equality comparer.
        * @param {Object} value The value to locate in the sequence.
        * @param {EqualityComparer=} comparer An equality comparer to compare values.
        * @returns {Boolean}
        */
        contains: function (value, comparer) {
            return contains(this, value, comparer);
        },

        /**
        * Returns the number of elements in a sequence.
        * @param {Function=} predicate A function to test each element for a condition. eg. function(item)
        * @returns {Number}
        */
        count: function (predicate) {
            return count(this, predicate);
        },

        /**
        * Returns the elements of the specified sequence or the specified value in a collection if the sequence is empty.
        * @param {Object=} defaultValue The value to return if the sequence is empty.
        * @returns {Iterable}
        */
        defaultIfEmpty: function (defaultValue) {
            return defaultIfEmpty(this, defaultValue);
        },

        /**
        * Produces the set difference of two sequences by using the EqualityComparer to compare values.
        * @param {EqualityComparer=} comparer An EqualityComparer to compare values.
        * @returns {Iterable}
        */
        distinct: function (comparer) {
            return distinct(this, comparer);
        },

        /**
        * Returns the element at a specified index in a sequence. Throws an error if the index is less than 0 or greater than or equal to the number of elements in source.
        * @param {Number} index The zero-based index of the element to retrieve.
        * @returns {Object}
        */
        elementAt: function (index) {
            return elementAt(this, index);
        },

        /**
        * Produces the set difference of two sequences by using the specified EqualityComparer to compare values.
        * @param {Iterable} second An Iterable whose elements that also occur in the first sequence will cause those elements to be removed from the returned sequence.
        * @param {EqualityComparer=} comparer An EqualityComparer to compare values.
        * @returns {Iterable}
        */
        except: function (second, comparer) {
            return exceptIntersect(this, second, comparer, false);
        },

        /**
        * Returns the first element in a sequence that satisfies a specified condition. this method throws an exception if there is no element in the sequence.
        * @param {Function=} predicate A function to test each source element for a condition. eg. function(item)
        * @returns {Object}
        */
        first: function (predicate) {
            return first(this, predicate);
        },

        /**
        * Returns the first element of the sequence that satisfies a condition or a default value if no such element is found.
        * @param {Function=} predicate A function to test each source element for a condition. eg. function(item)
        * @param {Object=} defaultValue The value to return if no element exists with specified condition.
        * @returns {Object}
        */
        firstOrDefault: function (predicate, defaultValue) {
            return firstOrDefault(this, predicate, defaultValue);
        },

        /**
        * Performs the specified action on each element of an Iterable.
        * @param {Function} action The action function to perform on each element of an Iterable. eg. function(item, index)
        * @param {Object=} thisArg Value to use as this when executing callback.
        */
        forEach: function (action, thisArg) {
            return forEach(this, action, thisArg);
        },

        /**
        * Groups the elements of a sequence according to a key selector function.
        * @param {Function} keySelector A function to extract the key for each element. eg. function(item)
        * @param {Function|EqualityComparer=} elementSelectorOrComparer A function to map each source element to an element in the Grouping. eg. function(item) or an equality comparer
        * @param {Function|EqualityComparer=} resultSelectorOrComparer A function to extract the key for each element. eg. function(item) or an equality comparer
        * @param {EqualityComparer=} comparer An equality comparer to compare values.
        * @returns {Iterable}
        */
        groupBy: function (keySelector, elementSelectorOrComparer, resultSelectorOrComparer, comparer) {
            var args = arguments.length,
                elementSelector = isFunction(elementSelectorOrComparer) ? elementSelectorOrComparer : null,
                resultSelector = isFunction(resultSelectorOrComparer) ? resultSelectorOrComparer : null;

            comparer = args === 3 && elementSelector === null ? elementSelectorOrComparer :
                (args === 4 && resultSelector === null ? resultSelectorOrComparer : comparer);

            return groupBy(this, keySelector, elementSelector, resultSelector, comparer);
        },

        /**
        * Correlates the elements of two sequences based on key equality and groups the results. A specified EqualityComparer is used to compare keys.
        * @param {Iterable} inner The sequence to join to the current sequence.
        * @param {Function} outerKeySelector A function to extract the join key from each element of the first sequence. eg. function(outer)
        * @param {Function} innerKeySelector A function to extract the join key from each element of the second sequence. function(inner)
        * @param {Function} resultSelector A function to create a result element from an element from the first sequence and a collection of matching elements from the second sequence. eg. function(outer, inner)
        * @param {EqualityComparer=} comparer An equality comparer to compare values.
        * @returns {Iterable}
        */
        groupJoin: function (inner, outerKeySelector, innerKeySelector, resultSelector, comparer) {
            return groupJoin(this, inner, outerKeySelector, innerKeySelector, resultSelector, comparer);
        },

        /**
        * Produces the set intersection of two sequences by using the default equality comparer to compare values.
        * @param {Iterable} second An Iterable whose distinct elements that also appear in the first sequence will be returned.
        * @param {EqualityComparer=} comparer An EqualityComparer to compare values.
        * @returns {Iterable}
        */
        intersect: function (second, comparer) {
            return exceptIntersect(this, second, comparer, true);
        },

        /**
        * Correlates the elements of two sequences based on matching keys. A specified EqualityComparer is used to compare keys.
        * @param {Iterable} inner The sequence to join to the current sequence.
        * @param {Function} outerKeySelector A function to extract the join key from each element of the first sequence. eg. function(outer)
        * @param {Function} innerKeySelector A function to extract the join key from each element of the second sequence. function(inner)
        * @param {Function} resultSelector A function to create a result element from an element from the first sequence and a collection of matching elements from the second sequence. eg. function(outer, inner)
        * @param {EqualityComparer=} comparer An equality comparer to compare values.
        * @returns {Iterable}
        */
        join: function (inner, outerKeySelector, innerKeySelector, resultSelector, comparer) {
            return join(this, inner, outerKeySelector, innerKeySelector, resultSelector, comparer);
        },

        /**
        * Returns the last element of a sequence that satisfies a specified condition.
        * @param {Function=} predicate A function to test each source element for a condition. eg. function(item)
        * @returns {Object}
        */
        last: function (predicate) {
            return last(this, predicate);
        },

        /**
        * Returns the last element of a sequence that satisfies a condition or a default value if no such element is found.
        * @param {Function=} predicate A function to test each source element for a condition. eg. function(item)
        * @param {Object=} defaultValue The value to return if no element exists with specified condition.
        * @returns {Object}
        */
        lastOrDefault: function (predicate, defaultValue) {
            return lastOrDefault(this, predicate, defaultValue);
        },

        /**
        * Invokes a transform function on each element of a sequence and returns the maximum value.
        * @param {Function=} selector A transform function to apply to each element. eg. function(item)
        * @returns {Object}
        */
        max: function (selector) {
            return minMax(this, true, selector);
        },

        /**
        * Invokes a transform function on each element of a sequence and returns the minimum value.
        * @param {Function=} selector A transform function to apply to each element. eg. function(item)
        * @returns {Object}
        */
        min: function (selector) {
            return minMax(this, false, selector);
        },

        /**
        * Filters the elements of an Iterable based on a specified type.
        * @param {Function} type The type to filter the elements of the sequence on.
        * @returns {Iterable}
        */
        ofType: function (type) {
            return ofType(this, type);
        },

        /**
        * Sorts the elements of a sequence in ascending order by using a specified comparer.
        * @param {Function} keySelector A function to extract a key from each element. eg. function(item)
        * @param {Comparer=} comparer A Comparer to compare keys.
        * @returns {OrderedIterable}
        */
        orderBy: function (keySelector, comparer) {
            return new OrderedIterable(this, keySelector, comparer, false);
        },

        /**
        * Sorts the elements of a sequence in descending order by using a specified comparer.
        * @param {Function} keySelector A function to extract a key from each element. eg. function(item)
        * @param {Comparer=} comparer A Comparer to compare keys.
        * @returns {OrderedIterable}
        */
        orderByDescending: function (keySelector, comparer) {
            return new OrderedIterable(this, keySelector, comparer, true);
        },

        /**
        * Inverts the order of the elements in a sequence.
        * @returns {Iterable}
        */
        reverse: function () {
            return reverse(this);
        },

        /**
        * Projects each element of a sequence into a new form.
        * @param {Function} selector A transform function to apply to each source element; the second parameter of the function represents the index of the source element. eg. function(item, index)
        * @returns {Iterable}
        */
        select: function (selector) {
            return select(this, selector);
        },

        /**
        * Projects each element of a sequence to an Iterable and flattens the resulting sequences into one sequence.
        * @param {Function} collectionSelector A transform function to apply to each source element; the second parameter of the function represents the index of the source element. eg. function(item, index)
        * @param {Function=} resultSelector A transform function to apply to each element of the intermediate sequence. eg. function(item, collection)
        * @returns {Iterable}
        */
        selectMany: function (collectionSelector, resultSelector) {
            return selectMany(this, collectionSelector, resultSelector);
        },

        /**
        * Determines whether two sequences are equal by comparing their elements by using an EqualityComparer.
        * @param {Iterable} second An Iterable to compare to the first sequence.
        * @param {EqualityComparer=} comparer The EqualityComparer to compare values.
        * @returns {Boolean}
        */
        sequenceEqual: function (second, comparer) {
            return sequenceEqual(this, second, comparer);
        },

        /**
        * Returns the only element of a sequence that satisfies a specified condition, and throws an exception if more than one such element exists.
        * @param {Function=} predicate A function to test each source element for a condition. eg. function(item)
        * @returns {Object}
        */
        single: function (predicate) {
            return single(this, predicate);
        },

        /**
        * Returns the only element of a sequence that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition.
        * @param {Function=} predicate A function to test each source element for a condition. eg. function(item)
        * @param {Object=} defaultValue The value to return if no element exists with specified condition.
        * @returns {Object}
        */
        singleOrDefault: function (predicate, defaultValue) {
            return singleOrDefault(this, predicate, defaultValue);
        },

        /**
        * Bypasses a specified number of elements in a sequence and then returns the remaining elements.
        * @param {Number} count The number of elements to skip before returning the remaining elements.
        * @returns {Iterable}
        */
        skip: function (count) {
            return skip(this, count);
        },

        /**
        * Bypasses elements in a sequence as long as a specified condition is true and then returns the remaining elements. The element's index is used in the logic of the predicate function.
        * @param {Function=} predicate A function to test each source element for a condition; the second parameter of the function represents the index of the source element. eg. function(item, index)
        * @returns {Iterable}
        */
        skipWhile: function (predicate) {
            return skipWhile(this, predicate);
        },

        /**
        * Computes the sum of the sequence of values that are obtained by invoking a transform function on each element of the input sequence.
        * @param {Function=} selector A transform function to apply to each element. eg. function(item)
        * @returns {Number}
        */
        sum: function (selector) {
            return sum(this, selector);
        },

        /**
        * Returns a specified number of contiguous elements from the start of a sequence.
        * @param {Number} count The number of elements to return.
        * @returns {Iterable}
        */
        take: function (count) {
            return take(this, count);
        },

        /**
        * Returns elements from a sequence as long as a specified condition is true. The element's index is used in the logic of the predicate function.
        * @param {Function=} predicate A function to test each source element for a condition; the second parameter of the function represents the index of the source element. eg. Function(item, index)
        * @returns {Iterable}
        */
        takeWhile: function (predicate) {
            return takeWhile(this, predicate);
        },

        /**
        * Creates a Dictionary from an Iterable according to a specified key selector function, a comparer, and an element selector function.
        * @param {Function} keySelector A function to extract a key from each element. eg. function(item)
        * @param {Function=} valueSelector A transform function to produce a result element value from each element. eg. function(item)
        * @param {EqualityComparer=} comparer An equality comparer to compare values.
        * @returns {Dictionary}
        */
        toDictionary: function (keySelector, valueSelector, comparer) {
            return toDictionary(this, keySelector, valueSelector, comparer);
        },

        /**
        * Creates an array from an Iterable.
        * @returns {Array}
        */
        toArray: function () {
            return buffer(this);
        },

        /**
        * Creates a List from an Iterable.
        * @returns {List}
        */
        toList: function () {
            return new List(this);
        },

        /**
        * Creates a Lookup from an Iterable according to a specified key selector function, a comparer and an element selector function.
        * @param {Function} keySelector A function to extract a key from each element. eg. function(item)
        * @param {Function=} valueSelector A transform function to produce a result element value from each element. eg. function(item)
        * @param {EqualityComparer=} comparer An equality comparer to compare values.
        * @returns {Lookup}
        */
        toLookup: function (keySelector, valueSelector, comparer) {
            return new Lookup(this, keySelector, valueSelector, comparer);
        },

        /**
        * Produces the set union of two sequences by using a specified EqualityComparer.
        * @param {Iterable} second An Iterable whose distinct elements form the second set for the union.
        * @param {EqualityComparer=} comparer The EqualityComparer to compare values.
        * @returns {Iterable}
        */
        union: function (second, comparer) {
            return union(this, second, comparer);
        },

        /**
         * Filters a sequence of values based on a predicate. Each element's index is used in the logic of the predicate function.
         * @param {Function} predicate A function to test each source element for a condition; the second parameter of the function represents the index of the source element. eg. function(item, index)
         * @returns {Iterable}
         */
        where: function (predicate) {
            return where(this, predicate);
        },

        /**
        * Merges two sequences by using the specified predicate function.
        * @param {Iterable} second The second sequence to merge.
        * @param {Function} resultSelector A function that specifies how to merge the elements from the two sequences. eg. function(first, second)
        * @returns {Iterable}
        */
        zip: function (second, resultSelector) {
            return zip(this, second, resultSelector);
        }
    });
}