README.md (6100B)
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 # doUntilEach 22 23 > Until a test condition is true, invoke a function for each element in a collection. 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 doUntilEach = require( '@stdlib/utils/do-until-each' ); 41 ``` 42 43 #### doUntilEach( collection, fcn, predicate\[, thisArg ] ) 44 45 Invokes a `function` for each element in a `collection` until either a `predicate` function returns `true` or the function has iterated over all `collection` elements. Note that the condition is evaluated **after** executing `fcn`; thus, `fcn` **always** executes at least once. 46 47 ```javascript 48 function predicate( value ) { 49 return ( value !== value ); 50 } 51 52 function log( value, index ) { 53 console.log( '%s: %d', index, value ); 54 } 55 56 var arr = [ 1, 2, 3, NaN, 4 ]; 57 58 doUntilEach( arr, log, predicate ); 59 /* => 60 0: 1 61 1: 2 62 2: 3 63 3: NaN 64 */ 65 ``` 66 67 Both the `predicate` function and the `function` to apply are provided three arguments: 68 69 - `value`: collection element 70 - `index`: collection index 71 - `collection`: input collection 72 73 If provided an empty `collection`, both `value` and `index` are `undefined`. 74 75 ```javascript 76 function predicate( value ) { 77 return ( value !== value ); 78 } 79 80 function log( value, index ) { 81 console.log( '%s: %s', index, value ); 82 } 83 84 var arr = []; 85 86 doUntilEach( arr, log, predicate ); 87 /* => 88 undefined: undefined 89 */ 90 ``` 91 92 Basic support for dynamic collections is provided. Note, however, that index incrementation is monotonically increasing. 93 94 ```javascript 95 function predicate( value ) { 96 return ( value !== value ); 97 } 98 99 function log1( value, index, collection ) { 100 console.log( '%s: %d', index, value ); 101 if ( index === collection.length-1 && collection.length < 10 ) { 102 collection.push( index+2 ); 103 } 104 } 105 106 var arr = [ 1, 2, 3, 4 ]; 107 108 doUntilEach( arr, log1, predicate ); 109 /* => 110 0: 1 111 1: 2 112 2: 3 113 3: 4 114 4: 5 115 5: 6 116 6: 7 117 7: 8 118 8: 9 119 9: 10 120 */ 121 122 function log2( value, index, collection ) { 123 console.log( '%s: %d', index, value ); 124 collection.shift(); 125 } 126 127 arr = [ 1, 2, 3, 4 ]; 128 129 doUntilEach( arr, log2, predicate ); 130 /* => 131 0: 1 132 1: 3 133 */ 134 ``` 135 136 To set the function execution context for the applied function, provide a `thisArg`. 137 138 ```javascript 139 function predicate( value ) { 140 return ( value > 2 ); 141 } 142 143 function sum( value ) { 144 this.sum += value; 145 this.count += 1; 146 } 147 148 var arr = [ 1, 2, 3, NaN, 4 ]; 149 150 var context = { 151 'sum': 0, 152 'count': 0 153 }; 154 155 doUntilEach( arr, sum, predicate, context ); 156 157 var mean = context.sum / context.count; 158 // returns 2.0 159 ``` 160 161 </section> 162 163 <!-- /.usage --> 164 165 <!-- Package usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. --> 166 167 <section class="notes"> 168 169 ## Notes 170 171 - 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`). 172 173 - The function returns the input `collection`. 174 175 - The function does **not** skip `undefined` elements. 176 177 <!-- eslint-disable no-sparse-arrays --> 178 179 ```javascript 180 function predicate( value ) { 181 return ( value !== value ); 182 } 183 184 function log( value, index ) { 185 console.log( '%s: %s', index, value ); 186 } 187 188 var arr = [ 1, , , 4 ]; 189 190 doUntilEach( arr, log, predicate ); 191 /* => 192 0: 1 193 1: undefined 194 2: undefined 195 3: 4 196 */ 197 ``` 198 199 - The function provides limited support for dynamic collections (i.e., collections whose `length` changes during execution). 200 201 </section> 202 203 <!-- /.notes --> 204 205 <!-- Package usage examples. --> 206 207 <section class="examples"> 208 209 ## Examples 210 211 <!-- eslint no-undef: "error" --> 212 213 ```javascript 214 var isEven = require( '@stdlib/assert/is-even' ).isPrimitive; 215 var randu = require( '@stdlib/random/base/randu' ); 216 var floor = require( '@stdlib/math/base/special/floor' ); 217 var doUntilEach = require( '@stdlib/utils/do-until-each' ); 218 219 function predicate( value ) { 220 return ( value !== value ); 221 } 222 223 function log( value, index, collection ) { 224 console.log( '%s: %d', index, value ); 225 if ( isEven( index ) ) { 226 collection.shift(); 227 } else { 228 collection.push( index+1 ); 229 } 230 } 231 232 var arr; 233 var j; 234 var i; 235 236 arr = new Array( 100 ); 237 j = floor( randu()*arr.length ); 238 for ( i = 0; i < arr.length; i++ ) { 239 if ( i === j ) { 240 arr[ i ] = NaN; 241 } else { 242 arr[ i ] = i; 243 } 244 } 245 246 doUntilEach( arr, log, predicate ); 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 [mdn-array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array 266 267 [mdn-typed-array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray 268 269 [mdn-object]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object 270 271 </section> 272 273 <!-- /.links -->