time-to-botec

Benchmark sampling in different programming languages
Log | Files | Refs | README

README.md (10752B)


      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 # bifurcateByAsync
     22 
     23 > Split 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 bifurcateByAsync = require( '@stdlib/utils/async/bifurcate-by' );
     41 ```
     42 
     43 #### bifurcateByAsync( collection, \[options,] predicate, done )
     44 
     45 Splits values into two groups according to a `predicate` function, which specifies which group an element in the input `collection` belongs to. If a `predicate` function calls a provided callback with a truthy group value, a collection element belongs to the first group; otherwise, a collection element belongs to the second group.
     46 
     47 ```javascript
     48 function predicate( value, next ) {
     49     setTimeout( onTimeout, value );
     50     function onTimeout() {
     51         console.log( value );
     52         next( null, (value > 2000) );
     53     }
     54 }
     55 
     56 function done( error, result ) {
     57     if ( error ) {
     58         throw error;
     59     }
     60     console.log( result );
     61 }
     62 
     63 var arr = [ 3000, 2500, 1000 ];
     64 
     65 bifurcateByAsync( arr, predicate, done );
     66 /* =>
     67     1000
     68     2500
     69     3000
     70     [ [ 2500, 3000 ], [ 1000 ] ]
     71 */
     72 ```
     73 
     74 The function accepts the following `options`:
     75 
     76 -   `limit`: the maximum number of pending invocations at any one time. Default: `infinity`.
     77 -   `series`: `boolean` indicating whether to sequentially invoke the `predicate` function for each `collection` element. If `true`, the function sets `options.limit=1`. Default: `false`.
     78 -   `returns`: specifies the output format. If the option equals `'values'`, the function returns group results as element values. If the option equals `'indices'`, the function returns group results as element indices. If the option equals `'*'`, the function returns group results as both element indices and values. Default: `'values'`.
     79 -   `thisArg`: the execution context for `predicate`.
     80 
     81 By default, the function returns group results as element values. To return element indices, set the `returns` option to `'indices'`.
     82 
     83 ```javascript
     84 function predicate( value, next ) {
     85     setTimeout( onTimeout, value );
     86     function onTimeout() {
     87         console.log( value );
     88         next( null, (value > 2000) );
     89     }
     90 }
     91 
     92 function done( error, result ) {
     93     if ( error ) {
     94         throw error;
     95     }
     96     console.log( result );
     97 }
     98 
     99 var arr = [ 3000, 2500, 1000 ];
    100 
    101 var opts = {
    102     'returns': 'indices'
    103 };
    104 bifurcateByAsync( arr, opts, predicate, done );
    105 /* =>
    106     1000
    107     2500
    108     3000
    109     [ [ 1, 0 ], [ 2 ] ]
    110 */
    111 ```
    112 
    113 To return index-value pairs, set the `returns` option to `'*'`.
    114 
    115 ```javascript
    116 function predicate( value, next ) {
    117     setTimeout( onTimeout, value );
    118     function onTimeout() {
    119         console.log( value );
    120         next( null, (value > 2000) );
    121     }
    122 }
    123 
    124 function done( error, result ) {
    125     if ( error ) {
    126         throw error;
    127     }
    128     console.log( result );
    129 }
    130 
    131 var arr = [ 3000, 2500, 1000 ];
    132 
    133 var opts = {
    134     'returns': '*'
    135 };
    136 bifurcateByAsync( arr, opts, predicate, done );
    137 /* =>
    138     1000
    139     2500
    140     3000
    141     [ [ [ 1, 2500 ], [ 0, 3000 ] ], [ [ 2, 1000 ] ] ]
    142 */
    143 ```
    144 
    145 By default, all elements are processed concurrently, which means that the function does **not** guarantee completion order. To process each `collection` element sequentially, set the `series` option to `true`.
    146 
    147 ```javascript
    148 function predicate( value, next ) {
    149     setTimeout( onTimeout, value );
    150     function onTimeout() {
    151         console.log( value );
    152         next( null, (value > 2000) );
    153     }
    154 }
    155 
    156 function done( error, result ) {
    157     if ( error ) {
    158         throw error;
    159     }
    160     console.log( result );
    161 }
    162 
    163 var arr = [ 3000, 2500, 1000 ];
    164 
    165 var opts = {
    166     'series': true
    167 };
    168 
    169 bifurcateByAsync( arr, opts, predicate, done );
    170 /* =>
    171     3000
    172     2500
    173     1000
    174     [ [ 3000, 2500 ], [ 1000 ] ]
    175 */
    176 ```
    177 
    178 To limit the maximum number of pending function invocations, set the `limit` option.
    179 
    180 ```javascript
    181 function predicate( value, next ) {
    182     setTimeout( onTimeout, value );
    183     function onTimeout() {
    184         console.log( value );
    185         next( null, (value > 2000) );
    186     }
    187 }
    188 
    189 function done( error, result ) {
    190     if ( error ) {
    191         throw error;
    192     }
    193     console.log( result );
    194 }
    195 
    196 var arr = [ 3000, 2500, 1000 ];
    197 
    198 var opts = {
    199     'limit': 2
    200 };
    201 
    202 bifurcateByAsync( arr, opts, predicate, done );
    203 /* =>
    204     2500
    205     3000
    206     1000
    207     [ [ 2500, 3000 ], [ 1000 ] ]
    208 */
    209 ```
    210 
    211 To set the execution context of the `predicate` function, set the `thisArg` option.
    212 
    213 ```javascript
    214 function predicate( value, next ) {
    215     this.count += 1;
    216     setTimeout( onTimeout, value );
    217     function onTimeout() {
    218         next( null, (value > 2000) );
    219     }
    220 }
    221 
    222 var arr = [ 3000, 2500, 1000 ];
    223 
    224 var context = {
    225     'count': 0
    226 };
    227 
    228 var opts = {
    229     'thisArg': context
    230 };
    231 
    232 bifurcateByAsync( arr, opts, predicate, done );
    233 
    234 function done( error, result ) {
    235     if ( error ) {
    236         throw error;
    237     }
    238     console.log( result );
    239     // => [ [ 2500, 3000 ], [ 1000 ] ]
    240 
    241     console.log( context.count );
    242     // => 3
    243 }
    244 ```
    245 
    246 When invoked, the `predicate` function is provided a maximum of four arguments:
    247 
    248 -   `value`: collection value.
    249 -   `index`: collection index.
    250 -   `collection`: the input `collection`.
    251 -   `next`: a callback which should be called once the `predicate` function has finished processing a collection `value`.
    252 
    253 The actual number of provided arguments depends on function `length`. If the `predicate` function accepts two arguments, the `predicate` function is provided `value` and `next`. If the `predicate` function accepts three arguments, the `predicate` function is provided `value`, `index`, and `next`. For every other `predicate` function signature, the `predicate` function is provided all four arguments.
    254 
    255 ```javascript
    256 function predicate( value, i, collection, next ) {
    257     console.log( 'collection: %s. %d: %d', collection.join( ',' ), i, value );
    258     setTimeout( onTimeout, value );
    259     function onTimeout() {
    260         console.log( value );
    261         next( null, (value > 2000) );
    262     }
    263 }
    264 
    265 function done( error, result ) {
    266     if ( error ) {
    267         throw error;
    268     }
    269     console.log( result );
    270 }
    271 
    272 var arr = [ 3000, 2500, 1000 ];
    273 
    274 bifurcateByAsync( arr, predicate, done );
    275 /* =>
    276     collection: 3000,2500,1000. 0: 3000
    277     collection: 3000,2500,1000. 1: 2500
    278     collection: 3000,2500,1000. 2: 1000
    279     1000
    280     2500
    281     3000
    282     [ [ 2500, 3000 ], [ 1000 ] ]
    283 */
    284 ```
    285 
    286 #### bifurcateByAsync.factory( \[options,] predicate )
    287 
    288 Returns a `function` which invokes a `predicate` function once for each element in a `collection`.
    289 
    290 ```javascript
    291 function predicate( value, next ) {
    292     setTimeout( onTimeout, value );
    293     function onTimeout() {
    294         console.log( value );
    295         next( null, (value > 2000) );
    296     }
    297 }
    298 
    299 function done( error, result ) {
    300     if ( error ) {
    301         throw error;
    302     }
    303     console.log( result );
    304 }
    305 
    306 var f = bifurcateByAsync.factory( predicate );
    307 
    308 var arr1 = [ 3000, 2500, 1000 ];
    309 
    310 f( arr1, done );
    311 /* =>
    312     1000
    313     2500
    314     3000
    315     [ [ 2500, 3000 ], [ 1000 ] ]
    316 */
    317 
    318 var arr2 = [ 300, 250, 100 ];
    319 
    320 f( arr2, done );
    321 /* =>
    322     100
    323     250
    324     300
    325     [ [], [ 100, 250, 300 ] ]
    326 */
    327 ```
    328 
    329 The function accepts the same `options` as `bifurcateByAsync()`.
    330 
    331 </section>
    332 
    333 <!-- /.usage -->
    334 
    335 <!-- Package usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
    336 
    337 <section class="notes">
    338 
    339 ## Notes
    340 
    341 -   A `collection` may be either an [`Array`][mdn-array], [`Typed Array`][mdn-typed-array], or an array-like [`Object`][mdn-object] (excluding `strings` and `functions`).
    342 -   If a provided function calls the `next` callback with a truthy `error` argument, the function suspends execution and immediately calls the `done` callback for subsequent `error` handling.
    343 -   The function does **not** support dynamic `collection` resizing.
    344 -   The function does **not** skip `undefined` elements.
    345 -   If provided an empty `collection`, the function calls the `done` callback with an empty `array` for the group results.
    346 -   **Neither** `bifurcateByAsync` nor the function returned by the `factory` method **guarantee** asynchronous execution. To guarantee asynchrony, wrap the `done` callback in a function which either executes at the end of the current stack (e.g., `nextTick`) or during a subsequent turn of the event loop (e.g., `setImmediate`, `setTimeout`).
    347 
    348 </section>
    349 
    350 <!-- /.notes -->
    351 
    352 <!-- Package usage examples. -->
    353 
    354 <section class="examples">
    355 
    356 ## Examples
    357 
    358 <!-- eslint no-undef: "error" -->
    359 
    360 ```javascript
    361 var resolve = require( 'path' ).resolve;
    362 var readFile = require( '@stdlib/fs/read-file' );
    363 var bifurcateByAsync = require( '@stdlib/utils/async/bifurcate-by' );
    364 
    365 var files = [
    366     resolve( __dirname, 'package.json' ),
    367     resolve( __dirname, 'README.md' ),
    368     resolve( __dirname, 'beep.boop.md' )
    369 ];
    370 
    371 function done( error, result ) {
    372     if ( error ) {
    373         throw error;
    374     }
    375     console.log( result );
    376 }
    377 
    378 function predicate( file, next ) {
    379     var opts = {
    380         'encoding': 'utf8'
    381     };
    382     readFile( file, opts, onFile );
    383 
    384     function onFile( error ) {
    385         if ( error ) {
    386             return next( null, false );
    387         }
    388         next( null, true );
    389     }
    390 }
    391 
    392 bifurcateByAsync( files, predicate, done );
    393 ```
    394 
    395 </section>
    396 
    397 <!-- /.examples -->
    398 
    399 <!-- 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. -->
    400 
    401 <section class="references">
    402 
    403 </section>
    404 
    405 <!-- /.references -->
    406 
    407 <!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
    408 
    409 <section class="links">
    410 
    411 [mdn-array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
    412 
    413 [mdn-typed-array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray
    414 
    415 [mdn-object]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
    416 
    417 </section>
    418 
    419 <!-- /.links -->