README.md (6598B)
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 # bifurcateIn 22 23 > Split an object's **own** and **inherited** property values into two groups according to a predicate 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 bifurcateIn = require( '@stdlib/utils/bifurcate-in' ); 41 ``` 42 43 #### bifurcateIn( obj, \[options,] predicate ) 44 45 Splits an object's **own** and **inherited** property values into two groups according to a `predicate` function, which specifies which group a value in the input `object` belongs to. If a `predicate` function returns a truthy value, a value belongs to the first group; otherwise, a value belongs to the second group. 46 47 ```javascript 48 function predicate( v ) { 49 return v[ 0 ] === 'b'; 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 = bifurcateIn( obj, predicate ); 65 // e.g., returns [ [ 'beep', 'boop', 'bar' ], [ 'foo' ] ] 66 ``` 67 68 A `predicate` function is provided two arguments: 69 70 - `value`: object value 71 - `key`: object index 72 73 ```javascript 74 function predicate( v, k ) { 75 console.log( '%s: %s', k, v ); 76 return v[ 0 ] === 'b'; 77 } 78 function Foo() { 79 this.a = 'beep'; 80 this.b = 'boop'; 81 return this; 82 } 83 84 Foo.prototype = Object.create( null ); 85 Foo.prototype.c = 'foo'; 86 Foo.prototype.d = 'bar'; 87 88 var obj = new Foo(); 89 90 var out = bifurcateIn( obj, predicate ); 91 // e.g., returns [ [ 'beep', 'boop', 'bar' ], [ 'foo' ] ] 92 ``` 93 94 The function accepts the following `options`: 95 96 - `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'`. 97 - `thisArg`: execution context. 98 99 By default, the function returns object values. To return object keys, set the `returns` option to `'keys'`. 100 101 ```javascript 102 function predicate( v ) { 103 return v[ 0 ] === 'b'; 104 } 105 function Foo() { 106 this.a = 'beep'; 107 this.b = 'boop'; 108 return this; 109 } 110 111 Foo.prototype = Object.create( null ); 112 Foo.prototype.c = 'foo'; 113 Foo.prototype.d = 'bar'; 114 115 var obj = new Foo(); 116 117 var opts = { 118 'returns': 'keys' 119 }; 120 var out = bifurcateIn( obj, opts, predicate ); 121 // e.g., returns [ [ 'a', 'b', 'd' ], [ 'c' ] ] 122 ``` 123 124 To return key-value pairs, set the `returns` option to `'*'`. 125 126 ```javascript 127 function predicate( v ) { 128 return v[ 0 ] === 'b'; 129 } 130 function Foo() { 131 this.a = 'beep'; 132 this.b = 'boop'; 133 return this; 134 } 135 136 Foo.prototype = Object.create( null ); 137 Foo.prototype.c = 'foo'; 138 Foo.prototype.d = 'bar'; 139 140 var obj = new Foo(); 141 142 var opts = { 143 'returns': '*' 144 }; 145 var out = bifurcateIn( obj, opts, predicate ); 146 // e.g., returns [ [ [ 'a', 'beep' ], [ 'b', 'boop ], [ 'd', 'bar' ] ], [ [ 'c', 'foo' ] ] ] 147 ``` 148 149 To set the `predicate` execution context, provide a `thisArg`. 150 151 ```javascript 152 function predicate( v ) { 153 this.count += 1; 154 return v[ 0 ] === 'b'; 155 } 156 157 function Foo() { 158 this.a = 'beep'; 159 this.b = 'boop'; 160 return this; 161 } 162 163 Foo.prototype = Object.create( null ); 164 Foo.prototype.c = 'foo'; 165 Foo.prototype.d = 'bar'; 166 167 var obj = new Foo(); 168 169 var context = { 170 'count': 0 171 }; 172 var opts = { 173 'thisArg': context 174 }; 175 var out = bifurcateIn( obj, opts, predicate ); 176 // e.g., returns [ [ 'beep', 'boop', 'bar' ], [ 'foo' ] ] 177 178 console.log( context.count ); 179 // => 4 180 ``` 181 182 </section> 183 184 <!-- /.usage --> 185 186 <!-- Package usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. --> 187 188 <section class="notes"> 189 190 ## Notes 191 192 - 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. 193 - Because iteration order is **not** guaranteed, result order is **not** guaranteed. 194 - The function determines the list of own **and** inherited 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. 195 196 </section> 197 198 <!-- /.notes --> 199 200 <!-- Package usage examples. --> 201 202 <section class="examples"> 203 204 ## Examples 205 206 <!-- eslint no-undef: "error" --> 207 208 ```javascript 209 var randu = require( '@stdlib/random/base/randu' ); 210 var fromCodePoint = require( '@stdlib/string/from-code-point' ); 211 var bifurcateIn = require( '@stdlib/utils/bifurcate-in' ); 212 213 var opts; 214 var key; 215 var obj; 216 var out; 217 var i; 218 219 function Foo() { 220 var key; 221 var i; 222 for ( i = 0; i < 50; i++ ) { 223 key = fromCodePoint( 147+i ); 224 this[ key ] = randu(); 225 } 226 return this; 227 } 228 229 Foo.prototype = Object.create( null ); 230 for ( i = 0; i < 50; i++ ) { 231 key = fromCodePoint( 97+i ); 232 Foo.prototype[ key ] = randu(); 233 } 234 235 // Generate a random object: 236 obj = new Foo(); 237 238 // Compute the groups... 239 function predicate( v ) { 240 return ( v < 0.5 ); 241 } 242 opts = { 243 'returns': '*' 244 }; 245 out = bifurcateIn( obj, opts, predicate ); 246 console.log( out ); 247 ``` 248 249 </section> 250 251 <!-- /.examples --> 252 253 <!-- 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. --> 254 255 <section class="references"> 256 257 </section> 258 259 <!-- /.references --> 260 261 <!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. --> 262 263 <section class="links"> 264 265 [ecma-262-for-in]: http://www.ecma-international.org/ecma-262/5.1/#sec-12.6.4 266 267 </section> 268 269 <!-- /.links -->