main.js (3820B)
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 isObjectLike = require( '@stdlib/assert/is-object-like' ); 24 var isFunction = require( '@stdlib/assert/is-function' ); 25 var validate = require( './validate.js' ); 26 var returnValues = require( './return_values.js' ); 27 var returnKeys = require( './return_keys.js' ); 28 var returnPairs = require( './return_pairs.js' ); 29 30 31 // MAIN // 32 33 /** 34 * Groups an object's own and inherited property values according to an indicator function. 35 * 36 * @param {(Object|Array|TypedArray)} obj - input object 37 * @param {Options} [options] - function options 38 * @param {*} [options.thisArg] - execution context 39 * @param {string} [options.returns="values"] - if `values`, values are returned; if `keys`, keys are returned; if `*`, both keys and values are returned 40 * @param {Function} indicator - indicator function indicating which group an element in the input object belongs to 41 * @throws {TypeError} first argument must be an object, array, or typed array 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 {Object} group results 46 * 47 * @example 48 * function indicator( v ) { 49 * return v[ 0 ]; 50 * } 51 * 52 * function Foo() { 53 * this.a = 'beep'; 54 * this.b = 'boop'; 55 * return this; 56 * } 57 * 58 * Foo.prototype = Object.create( null ); 59 * Foo.prototype.c = 'foo'; 60 * Foo.prototype.d = 'bar'; 61 * 62 * var obj = new Foo(); 63 * 64 * var out = groupIn( obj, indicator ); 65 * // e.g., returns { 'b': [ 'beep', 'boop', 'bar' ], 'f': [ 'foo' ] } 66 * 67 * @example 68 * function indicator( v ) { 69 * return v[ 0 ]; 70 * } 71 * 72 * function Foo() { 73 * this.a = 'beep'; 74 * this.b = 'boop'; 75 * return this; 76 * } 77 * 78 * Foo.prototype = Object.create( null ); 79 * Foo.prototype.c = 'foo'; 80 * Foo.prototype.d = 'bar'; 81 * 82 * var obj = new Foo(); 83 * 84 * var opts = { 85 * 'returns': 'keys' 86 * }; 87 * var out = groupIn( obj, opts, indicator ); 88 * // e.g., returns { 'b': [ 'a', 'b', 'd' ], 'f': [ 'c' ] } 89 * 90 * @example 91 * function indicator( v ) { 92 * return v[ 0 ]; 93 * } 94 * 95 * function Foo() { 96 * this.a = 'beep'; 97 * this.b = 'boop'; 98 * return this; 99 * } 100 * 101 * Foo.prototype = Object.create( null ); 102 * Foo.prototype.c = 'foo'; 103 * Foo.prototype.d = 'bar'; 104 * 105 * var obj = new Foo(); 106 * 107 * var opts = { 108 * 'returns': '*' 109 * }; 110 * var out = groupIn( obj, opts, indicator ); 111 * // e.g., returns { 'b': [ [ 'a', 'beep' ], [ 'b', 'boop' ], [ 'd', 'bar' ] ], 'f': [ [ 'c', 'foo' ] ] } 112 */ 113 function groupIn( obj, options, indicator ) { 114 var opts; 115 var err; 116 var cb; 117 if ( !isObjectLike( obj ) ) { 118 throw new TypeError( 'invalid argument. First argument must be an object. Value: `'+obj+'`.' ); 119 } 120 opts = { 121 'returns': 'values' 122 }; 123 if ( arguments.length === 2 ) { 124 cb = options; 125 } else { 126 err = validate( opts, options ); 127 if ( err ) { 128 throw err; 129 } 130 cb = indicator; 131 } 132 if ( !isFunction( cb ) ) { 133 throw new TypeError( 'invalid argument. Last argument must be a function. Value: `'+cb+'`.' ); 134 } 135 if ( opts.returns === 'values' ) { 136 return returnValues( obj, opts, cb ); 137 } 138 if ( opts.returns === 'keys' ) { 139 return returnKeys( obj, opts, cb ); 140 } 141 return returnPairs( obj, opts, cb ); 142 } 143 144 145 // EXPORTS // 146 147 module.exports = groupIn;