1var apply = require('./_apply'),
2    arrayMap = require('./_arrayMap'),
3    baseIteratee = require('./_baseIteratee'),
4    baseRest = require('./_baseRest');
5
6/** Error message constants. */
7var FUNC_ERROR_TEXT = 'Expected a function';
8
9/**
10 * Creates a function that iterates over `pairs` and invokes the corresponding
11 * function of the first predicate to return truthy. The predicate-function
12 * pairs are invoked with the `this` binding and arguments of the created
13 * function.
14 *
15 * @static
16 * @memberOf _
17 * @since 4.0.0
18 * @category Util
19 * @param {Array} pairs The predicate-function pairs.
20 * @returns {Function} Returns the new composite function.
21 * @example
22 *
23 * var func = _.cond([
24 *   [_.matches({ 'a': 1 }),           _.constant('matches A')],
25 *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
26 *   [_.stubTrue,                      _.constant('no match')]
27 * ]);
28 *
29 * func({ 'a': 1, 'b': 2 });
30 * // => 'matches A'
31 *
32 * func({ 'a': 0, 'b': 1 });
33 * // => 'matches B'
34 *
35 * func({ 'a': '1', 'b': '2' });
36 * // => 'no match'
37 */
38function cond(pairs) {
39  var length = pairs == null ? 0 : pairs.length,
40      toIteratee = baseIteratee;
41
42  pairs = !length ? [] : arrayMap(pairs, function(pair) {
43    if (typeof pair[1] != 'function') {
44      throw new TypeError(FUNC_ERROR_TEXT);
45    }
46    return [toIteratee(pair[0]), pair[1]];
47  });
48
49  return baseRest(function(args) {
50    var index = -1;
51    while (++index < length) {
52      var pair = pairs[index];
53      if (apply(pair[0], this, args)) {
54        return apply(pair[1], this, args);
55      }
56    }
57  });
58}
59
60module.exports = cond;
61