time-to-botec

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

README.md (9491B)


      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 # tabulateByAsync
     22 
     23 > Generate a frequency table 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 tabulateByAsync = require( '@stdlib/utils/async/tabulate-by' );
     41 ```
     42 
     43 #### tabulateByAsync( collection, \[options,] indicator, done )
     44 
     45 Generates a frequency table according to an `indicator` function, i.e., a function which specifies how to categorize an element in the input `collection`.
     46 
     47 ```javascript
     48 function indicator( 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, 750 ];
     64 
     65 tabulateByAsync( arr, indicator, done );
     66 /* =>
     67     750
     68     1000
     69     2500
     70     3000
     71     [ [ false, 2, 0.5 ], [ true, 2, 0.5 ] ]
     72 */
     73 ```
     74 
     75 The returned frequency table is an `array` of `arrays`. Each sub-array corresponds to a unique value in the input `collection` and is structured as follows:
     76 
     77 -   `0`: unique value
     78 -   `1`: value count
     79 -   `2`: frequency percentage
     80 
     81 The function accepts the following `options`:
     82 
     83 -   `limit`: the maximum number of pending invocations at any one time. Default: `infinity`.
     84 -   `series`: `boolean` indicating whether to sequentially invoke the `indicator` function for each `collection` element. If `true`, the function sets `options.limit=1`. Default: `false`.
     85 -   `thisArg`: the execution context for `indicator`.
     86 
     87 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`.
     88 
     89 ```javascript
     90 function indicator( value, next ) {
     91     setTimeout( onTimeout, value );
     92     function onTimeout() {
     93         console.log( value );
     94         next( null, (value > 2000) );
     95     }
     96 }
     97 
     98 function done( error, result ) {
     99     if ( error ) {
    100         throw error;
    101     }
    102     console.log( result );
    103 }
    104 
    105 var arr = [ 3000, 2500, 1000, 750 ];
    106 
    107 var opts = {
    108     'series': true
    109 };
    110 
    111 tabulateByAsync( arr, opts, indicator, done );
    112 /* =>
    113     3000
    114     2500
    115     1000
    116     750
    117     [ [ true, 2, 0.5 ], [ false, 2, 0.5 ] ]
    118 */
    119 ```
    120 
    121 To limit the maximum number of pending function invocations, set the `limit` option.
    122 
    123 ```javascript
    124 function indicator( value, next ) {
    125     setTimeout( onTimeout, value );
    126     function onTimeout() {
    127         console.log( value );
    128         next( null, (value > 2000) );
    129     }
    130 }
    131 
    132 function done( error, result ) {
    133     if ( error ) {
    134         throw error;
    135     }
    136     console.log( result );
    137 }
    138 
    139 var arr = [ 3000, 2500, 1000, 750 ];
    140 
    141 var opts = {
    142     'limit': 2
    143 };
    144 
    145 tabulateByAsync( arr, opts, indicator, done );
    146 /* =>
    147     2500
    148     3000
    149     1000
    150     750
    151     [ [ true, 2, 0.5 ], [ false, 2, 0.5 ] ]
    152 */
    153 ```
    154 
    155 To set the execution context of the `indicator` function, set the `thisArg` option.
    156 
    157 ```javascript
    158 function indicator( value, next ) {
    159     this.count += 1;
    160     setTimeout( onTimeout, value );
    161     function onTimeout() {
    162         next( null, (value > 2000) );
    163     }
    164 }
    165 
    166 var arr = [ 3000, 2500, 1000, 750 ];
    167 
    168 var context = {
    169     'count': 0
    170 };
    171 
    172 var opts = {
    173     'thisArg': context
    174 };
    175 
    176 tabulateByAsync( arr, opts, indicator, done );
    177 
    178 function done( error, result ) {
    179     if ( error ) {
    180         throw error;
    181     }
    182     console.log( result );
    183     // => [ [ false, 2, 0.5 ], [ true, 2, 0.5 ] ]
    184 
    185     console.log( context.count );
    186     // => 4
    187 }
    188 ```
    189 
    190 When invoked, the `indicator` function is provided a maximum of four arguments:
    191 
    192 -   `value`: collection value.
    193 -   `index`: collection index.
    194 -   `collection`: the input `collection`.
    195 -   `next`: a callback which should be called once the `indicator` function has finished processing a collection `value`.
    196 
    197 The actual number of provided arguments depends on function `length`. If the `indicator` function accepts two arguments, the `indicator` function is provided `value` and `next`. If the `indicator` function accepts three arguments, the `indicator` function is provided `value`, `index`, and `next`. For every other `indicator` function signature, the `indicator` function is provided all four arguments.
    198 
    199 ```javascript
    200 function indicator( value, i, collection, next ) {
    201     console.log( 'collection: %s. %d: %d', collection.join( ',' ), i, value );
    202     setTimeout( onTimeout, value );
    203     function onTimeout() {
    204         console.log( value );
    205         next( null, (value > 2000) );
    206     }
    207 }
    208 
    209 function done( error, result ) {
    210     if ( error ) {
    211         throw error;
    212     }
    213     console.log( result );
    214 }
    215 
    216 var arr = [ 3000, 2500, 1000, 750 ];
    217 
    218 tabulateByAsync( arr, indicator, done );
    219 /* =>
    220     collection: 3000,2500,1000,750. 0: 3000
    221     collection: 3000,2500,1000,750. 1: 2500
    222     collection: 3000,2500,1000,750. 2: 1000
    223     collection: 3000,2500,1000,750. 3: 750
    224     750
    225     1000
    226     2500
    227     3000
    228     [ [ false, 2, 0.5 ], [ true, 2, 0.5 ] ]
    229 */
    230 ```
    231 
    232 #### tabulateByAsync.factory( \[options,] indicator )
    233 
    234 Returns a `function` which invokes an `indicator` function once for each element in a `collection` and generates a frequency table.
    235 
    236 ```javascript
    237 function indicator( value, next ) {
    238     setTimeout( onTimeout, value );
    239     function onTimeout() {
    240         console.log( value );
    241         next( null, (value > 2000) );
    242     }
    243 }
    244 
    245 function done( error, result ) {
    246     if ( error ) {
    247         throw error;
    248     }
    249     console.log( result );
    250 }
    251 
    252 var f = tabulateByAsync.factory( indicator );
    253 
    254 var arr1 = [ 3000, 2500, 1000, 750 ];
    255 
    256 f( arr1, done );
    257 /* =>
    258     750
    259     1000
    260     2500
    261     3000
    262     [ [ false, 2, 0.5 ], [ true, 2, 0.5 ] ]
    263 */
    264 
    265 var arr2 = [ 300, 250, 100 ];
    266 
    267 f( arr2, done );
    268 /* =>
    269     100
    270     250
    271     300
    272     [ [ false, 3, 1.0 ] ]
    273 */
    274 ```
    275 
    276 The function accepts the same `options` as `tabulateByAsync()`.
    277 
    278 </section>
    279 
    280 <!-- /.usage -->
    281 
    282 <!-- Package usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
    283 
    284 <section class="notes">
    285 
    286 ## Notes
    287 
    288 -   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`).
    289 -   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.
    290 -   The function does **not** support dynamic `collection` resizing.
    291 -   The function does **not** skip `undefined` elements.
    292 -   If provided an empty `collection`, the function calls the `done` callback with an empty `array` for the tabulated results.
    293 -   **Neither** `tabulateByAsync` 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`).
    294 
    295 </section>
    296 
    297 <!-- /.notes -->
    298 
    299 <!-- Package usage examples. -->
    300 
    301 <section class="examples">
    302 
    303 ## Examples
    304 
    305 <!-- eslint no-undef: "error" -->
    306 
    307 ```javascript
    308 var resolve = require( 'path' ).resolve;
    309 var readFile = require( '@stdlib/fs/read-file' );
    310 var tabulateByAsync = require( '@stdlib/utils/async/tabulate-by' );
    311 
    312 var files = [
    313     resolve( __dirname, 'package.json' ),
    314     resolve( __dirname, 'README.md' ),
    315     resolve( __dirname, 'beep.boop.md' )
    316 ];
    317 
    318 function done( error, result ) {
    319     if ( error ) {
    320         throw error;
    321     }
    322     console.log( result );
    323 }
    324 
    325 function indicator( file, next ) {
    326     var opts = {
    327         'encoding': 'utf8'
    328     };
    329     readFile( file, opts, onFile );
    330 
    331     function onFile( error ) {
    332         if ( error ) {
    333             return next( null, 'nonreadable' );
    334         }
    335         next( null, 'readable' );
    336     }
    337 }
    338 
    339 tabulateByAsync( files, indicator, done );
    340 ```
    341 
    342 </section>
    343 
    344 <!-- /.examples -->
    345 
    346 <!-- 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. -->
    347 
    348 <section class="references">
    349 
    350 </section>
    351 
    352 <!-- /.references -->
    353 
    354 <!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
    355 
    356 <section class="links">
    357 
    358 [mdn-array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
    359 
    360 [mdn-typed-array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray
    361 
    362 [mdn-object]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
    363 
    364 </section>
    365 
    366 <!-- /.links -->