README.md (6167B)
1 <!-- 2 3 @license Apache-2.0 4 5 Copyright (c) 2018 The Stdlib Authors. 6 7 Licensed under the Apache License, Version 2.0 (the "License"); 8 you may not use this file except in compliance with the License. 9 You may obtain a copy of the License at 10 11 http://www.apache.org/licenses/LICENSE-2.0 12 13 Unless required by applicable law or agreed to in writing, software 14 distributed under the License is distributed on an "AS IS" BASIS, 15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 See the License for the specific language governing permissions and 17 limitations under the License. 18 19 --> 20 21 # groupOwn 22 23 > Group an object's **own** property values according to an indicator function. 24 25 <!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. --> 26 27 <section class="intro"> 28 29 </section> 30 31 <!-- /.intro --> 32 33 <!-- Package usage documentation. --> 34 35 <section class="usage"> 36 37 ## Usage 38 39 ```javascript 40 var groupOwn = require( '@stdlib/utils/group-own' ); 41 ``` 42 43 #### groupOwn( obj, \[options,] indicator ) 44 45 Groups an object's **own** property values according to an `indicator` function, which specifies which group a value in the input `object` belongs to. 46 47 ```javascript 48 function indicator( v ) { 49 return v[ 0 ]; 50 } 51 var obj = { 52 'a': 'beep', 53 'b': 'boop', 54 'c': 'foo', 55 'd': 'bar' 56 }; 57 58 var out = groupOwn( obj, indicator ); 59 // e.g., returns { 'b': [ 'beep', 'boop', 'bar' ], 'f': [ 'foo' ] } 60 ``` 61 62 An `indicator` function is provided two arguments: 63 64 - `value`: object value 65 - `key`: object index 66 67 ```javascript 68 function indicator( v, k ) { 69 console.log( '%s: %s', k, v ); 70 return v[ 0 ]; 71 } 72 var obj = { 73 'a': 'beep', 74 'b': 'boop', 75 'c': 'foo', 76 'd': 'bar' 77 }; 78 79 var out = groupOwn( obj, indicator ); 80 // e.g., returns { 'b': [ 'beep', 'boop', 'bar' ], 'f': [ 'foo' ] } 81 ``` 82 83 The function accepts the following `options`: 84 85 - `returns`: specifies the output format. If the option equals `'values'`, the function outputs values. If the option equals `'keys'`, the function outputs keys. If the option equals `'*'`, the function outputs both keys and values. Default: `'values'`. 86 - `thisArg`: execution context. 87 88 By default, the function returns object values. To return object keys, set the `returns` option to `'keys'`. 89 90 ```javascript 91 function indicator( v ) { 92 return v[ 0 ]; 93 } 94 var obj = { 95 'a': 'beep', 96 'b': 'boop', 97 'c': 'foo', 98 'd': 'bar' 99 }; 100 101 var opts = { 102 'returns': 'keys' 103 }; 104 var out = groupOwn( obj, opts, indicator ); 105 // e.g., returns { 'b': [ 'a', 'b', 'd' ], 'f': [ 'c' ] } 106 ``` 107 108 To return key-value pairs, set the `returns` option to `'*'`. 109 110 ```javascript 111 function indicator( v ) { 112 return v[ 0 ]; 113 } 114 var obj = { 115 'a': 'beep', 116 'b': 'boop', 117 'c': 'foo', 118 'd': 'bar' 119 }; 120 121 var opts = { 122 'returns': '*' 123 }; 124 var out = groupOwn( obj, opts, indicator ); 125 // e.g., returns { 'b': [ [ 'a', 'beep' ], [ 'b', 'boop ], [ 'd', 'bar' ] ], 'f': [ [ 'c', 'foo' ] ] } 126 ``` 127 128 To set the `indicator` execution context, provide a `thisArg`. 129 130 ```javascript 131 function indicator( v ) { 132 this.count += 1; 133 return v[ 0 ]; 134 } 135 var context = { 136 'count': 0 137 }; 138 var opts = { 139 'thisArg': context 140 }; 141 var obj = { 142 'a': 'beep', 143 'b': 'boop', 144 'c': 'foo', 145 'd': 'bar' 146 }; 147 var out = groupOwn( obj, opts, indicator ); 148 // e.g., returns { 'b': [ 'beep', 'boop', 'bar' ], 'f': [ 'foo' ] } 149 150 console.log( context.count ); 151 // => 4 152 ``` 153 154 </section> 155 156 <!-- /.usage --> 157 158 <!-- Package usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. --> 159 160 <section class="notes"> 161 162 ## Notes 163 164 - Iteration order is **not** guaranteed, as `object` key enumeration is not specified according to the [ECMAScript specification][ecma-262-for-in]. In practice, however, most engines use insertion order to sort an `object`'s keys, thus allowing for deterministic iteration. 165 166 - Because iteration order is **not** guaranteed, result order is **not** guaranteed. 167 168 - The function determines the list of own enumerable properties **before** invoking the provided function. Hence, any modifications made to the input `object` **after** calling this function (such as adding and removing properties) will **not** affect the list of visited properties. 169 170 - The value returned by an `indicator` function should be a value which can be serialized as an `object` key. As a counterexample, 171 172 ```javascript 173 function indicator( v ) { 174 return {}; 175 } 176 var obj = { 177 'a': 'beep', 178 'b': 'boop', 179 'c': 'foo', 180 'd': 'bar' 181 }; 182 var out = groupOwn( obj, indicator ); 183 // e.g., returns { '[object Object]': [ 'beep', 'boop', 'foo', 'bar' ] } 184 ``` 185 186 while each group identifier is unique, all object values resolve to the same group because each group identifier serializes to the same `string`. 187 188 </section> 189 190 <!-- /.notes --> 191 192 <!-- Package usage examples. --> 193 194 <section class="examples"> 195 196 ## Examples 197 198 <!-- eslint no-undef: "error" --> 199 200 ```javascript 201 var randu = require( '@stdlib/random/base/randu' ); 202 var fromCodePoint = require( '@stdlib/string/from-code-point' ); 203 var groupOwn = require( '@stdlib/utils/group-own' ); 204 205 var key; 206 var obj; 207 var out; 208 var i; 209 210 // Generate a random object... 211 obj = {}; 212 for ( i = 0; i < 100; i++ ) { 213 key = fromCodePoint( 97+i ); 214 obj[ key ] = randu(); 215 } 216 217 function indicator( v ) { 218 if ( v < 0.5 ) { 219 return 'low'; 220 } 221 return 'high'; 222 } 223 224 // Compute the groups: 225 out = groupOwn( obj, indicator ); 226 console.log( out ); 227 ``` 228 229 </section> 230 231 <!-- /.examples --> 232 233 <!-- Section to include cited references. If references are included, add a horizontal rule *before* the section. Make sure to keep an empty line after the `section` element and another before the `/section` close. --> 234 235 <section class="references"> 236 237 </section> 238 239 <!-- /.references --> 240 241 <!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. --> 242 243 <section class="links"> 244 245 [ecma-262-for-in]: http://www.ecma-international.org/ecma-262/5.1/#sec-12.6.4 246 247 </section> 248 249 <!-- /.links -->