bifurcate_by.js (3340B)
1 /** 2 * @license Apache-2.0 3 * 4 * Copyright (c) 2018 The Stdlib Authors. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 'use strict'; 20 21 // MODULES // 22 23 var isCollection = require( '@stdlib/assert/is-collection' ); 24 var isFunction = require( '@stdlib/assert/is-function' ); 25 var validate = require( './validate.js' ); 26 var returnValues = require( './return_values.js' ); 27 var returnIndices = require( './return_indices.js' ); 28 var returnPairs = require( './return_pairs.js' ); 29 30 31 // MAIN // 32 33 /** 34 * Splits values into two groups according to a predicate function. 35 * 36 * @param {Collection} collection - input collection 37 * @param {Options} [options] - function options 38 * @param {*} [options.thisArg] - execution context 39 * @param {string} [options.returns="values"] - if `values`, values are returned; if `indices`, indices are returned; if `*`, both indices and values are returned 40 * @param {Function} predicate - predicate function indicating which group an element in the input collection belongs to 41 * @throws {TypeError} first argument must be a collection 42 * @throws {TypeError} options argument must be an object 43 * @throws {TypeError} last argument must be a function 44 * @throws {TypeError} must provide valid options 45 * @returns {(Array<Array>|Array)} group results 46 * 47 * @example 48 * function predicate( v ) { 49 * return v[ 0 ] === 'b'; 50 * } 51 * var arr = [ 'beep', 'boop', 'foo', 'bar' ]; 52 * 53 * var out = bifurcateBy( arr, predicate ); 54 * // returns [ [ 'beep', 'boop', 'bar' ], [ 'foo' ] ] 55 * 56 * @example 57 * function predicate( v ) { 58 * return v[ 0 ] === 'b'; 59 * } 60 * var arr = [ 'beep', 'boop', 'foo', 'bar' ]; 61 * 62 * var opts = { 63 * 'returns': 'indices' 64 * }; 65 * var out = bifurcateBy( arr, opts, predicate ); 66 * // returns [ [ 0, 1, 3 ], [ 2 ] ] 67 * 68 * @example 69 * function predicate( v ) { 70 * return v[ 0 ] === 'b'; 71 * } 72 * var arr = [ 'beep', 'boop', 'foo', 'bar' ]; 73 * 74 * var opts = { 75 * 'returns': '*' 76 * }; 77 * var out = bifurcateBy( arr, opts, predicate ); 78 * // returns [ [ [ 0, 'beep' ], [ 1, 'boop' ], [ 3, 'bar' ] ], [ [ 2, 'foo' ] ] ] 79 */ 80 function bifurcateBy( collection, options, predicate ) { 81 var opts; 82 var err; 83 var cb; 84 if ( !isCollection( collection ) ) { 85 throw new TypeError( 'invalid argument. First argument must be a collection. Value: `'+collection+'`.' ); 86 } 87 opts = { 88 'returns': 'values' 89 }; 90 if ( arguments.length === 2 ) { 91 cb = options; 92 } else { 93 err = validate( opts, options ); 94 if ( err ) { 95 throw err; 96 } 97 cb = predicate; 98 } 99 if ( !isFunction( cb ) ) { 100 throw new TypeError( 'invalid argument. Last argument must be a function. Value: `'+cb+'`.' ); 101 } 102 if ( opts.returns === 'values' ) { 103 return returnValues( collection, opts, cb ); 104 } 105 if ( opts.returns === 'indices' ) { 106 return returnIndices( collection, opts, cb ); 107 } 108 return returnPairs( collection, opts, cb ); 109 } 110 111 112 // EXPORTS // 113 114 module.exports = bifurcateBy;