-
-
Notifications
You must be signed in to change notification settings - Fork 447
Commit
PR-URL: #2826 Closes: #2338 Co-authored-by: Gururaj Gurram <[email protected]> Co-authored-by: Philipp Burckhardt <[email protected]> Reviewed-by: Philipp Burckhardt <[email protected]> Signed-off-by: Gururaj Gurram <[email protected]>
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,207 @@ | ||
<!-- | ||
@license Apache-2.0 | ||
Copyright (c) 2024 The Stdlib Authors. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
--> | ||
|
||
# iterCuSomeBy | ||
|
||
> Create an iterator which cumulatively tests whether at least `n` iterated values pass a test implemented by a predicate function. | ||
<!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. --> | ||
|
||
<section class="intro"> | ||
|
||
</section> | ||
|
||
<!-- /.intro --> | ||
|
||
<!-- Package usage documentation. --> | ||
|
||
<section class="usage"> | ||
|
||
## Usage | ||
|
||
```javascript | ||
var iterCuSomeBy = require( '@stdlib/iter/cusome-by' ); | ||
``` | ||
|
||
#### iterCuSomeBy( iterator, n, predicate\[, thisArg] ) | ||
|
||
Returns an [iterator][mdn-iterator-protocol] which cumulatively tests whether at least `n` iterated values pass a test implemented by a `predicate` function. | ||
|
||
```javascript | ||
var array2iterator = require( '@stdlib/array/to-iterator' ); | ||
|
||
function isPositive( v ) { | ||
return ( v > 0 ); | ||
} | ||
|
||
var arr = array2iterator( [ 0, 0, 0, 1, 1 ] ); | ||
|
||
var it = iterCuSomeBy( arr, 2, isPositive ); | ||
|
||
var v = it.next().value; | ||
// returns false | ||
|
||
v = it.next().value; | ||
// returns false | ||
|
||
v = it.next().value; | ||
// returns false | ||
|
||
v = it.next().value; | ||
// returns false | ||
|
||
v = it.next().value; | ||
// returns true | ||
|
||
var bool = it.next().done; | ||
// returns true | ||
``` | ||
|
||
The returned [iterator][mdn-iterator-protocol] protocol-compliant object has the following properties: | ||
|
||
- **next**: function which returns an [iterator][mdn-iterator-protocol] protocol-compliant object containing the next iterated value (if one exists) assigned to a `value` property and a `done` property having a `boolean` value indicating whether the [iterator][mdn-iterator-protocol] is finished. | ||
- **return**: function which closes an [iterator][mdn-iterator-protocol] and returns a single (optional) argument in an [iterator][mdn-iterator-protocol] protocol-compliant object. | ||
|
||
A `predicate` function is provided two arguments: | ||
|
||
- **value**: iterated value | ||
- **index**: iteration index (zero-based) | ||
|
||
To set the `predicate` function execution context, provide a `thisArg`. | ||
|
||
<!-- eslint-disable no-invalid-this --> | ||
|
||
```javascript | ||
var array2iterator = require( '@stdlib/array/to-iterator' ); | ||
|
||
function predicate( v ) { | ||
this.count += 1; | ||
return ( v > 0 ); | ||
} | ||
|
||
var arr = array2iterator( [ 0, 0, 1, 1, 1 ] ); | ||
|
||
var ctx = { | ||
'count': 0 | ||
}; | ||
|
||
var it = iterCuSomeBy( arr, 3, predicate, ctx ); | ||
// returns <Object> | ||
|
||
var v = it.next().value; | ||
// returns false | ||
|
||
v = it.next().value; | ||
// returns false | ||
|
||
v = it.next().value; | ||
// returns false | ||
|
||
v = it.next().value; | ||
// returns false | ||
|
||
v = it.next().value; | ||
// returns true | ||
|
||
var count = ctx.count; | ||
// returns 5 | ||
``` | ||
|
||
</section> | ||
|
||
<!-- /.usage --> | ||
|
||
<!-- Package usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. --> | ||
|
||
<section class="notes"> | ||
|
||
## Notes | ||
|
||
- A `predicate` function is invoked for each iterated value until the `nth` truthy `predicate` function return value. The returned iterator continues iterating until it reaches the end of the input iterator, even after the condition is met. | ||
This comment has been minimized.
Sorry, something went wrong. |
||
|
||
</section> | ||
|
||
<!-- /.notes --> | ||
|
||
<!-- Package usage examples. --> | ||
|
||
<section class="examples"> | ||
|
||
## Examples | ||
|
||
<!-- eslint no-undef: "error" --> | ||
|
||
```javascript | ||
var randu = require( '@stdlib/random/iter/randu' ); | ||
var iterCuSomeBy = require( '@stdlib/iter/cusome-by' ); | ||
|
||
function threshold( r ) { | ||
return ( r > 0.95 ); | ||
} | ||
|
||
// Create an iterator which generates uniformly distributed pseudorandom numbers: | ||
var opts = { | ||
'iter': 100 | ||
}; | ||
var riter = randu( opts ); | ||
|
||
// Create an iterator which tracks whether at least two values have exceeded the threshold: | ||
This comment has been minimized.
Sorry, something went wrong. |
||
var it = iterCuSomeBy( riter, 2, threshold ); | ||
|
||
// Perform manual iteration... | ||
var r; | ||
while ( true ) { | ||
r = it.next(); | ||
if ( r.done ) { | ||
break; | ||
} | ||
console.log( r.value ); | ||
} | ||
``` | ||
|
||
</section> | ||
|
||
<!-- /.examples --> | ||
|
||
<!-- 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. --> | ||
|
||
<section class="references"> | ||
|
||
</section> | ||
|
||
<!-- /.references --> | ||
|
||
<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. --> | ||
|
||
<section class="related"> | ||
|
||
</section> | ||
|
||
<!-- /.related --> | ||
|
||
<!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. --> | ||
|
||
<section class="links"> | ||
|
||
[mdn-iterator-protocol]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#The_iterator_protocol | ||
|
||
</section> | ||
|
||
<!-- /.links --> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/** | ||
* @license Apache-2.0 | ||
* | ||
* Copyright (c) 2024 The Stdlib Authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
'use strict'; | ||
|
||
// MODULES // | ||
|
||
var bench = require( '@stdlib/bench' ); | ||
var iterConstant = require( '@stdlib/iter/constant' ); | ||
var isIteratorLike = require( '@stdlib/assert/is-iterator-like' ); | ||
var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive; | ||
var pkg = require( './../package.json' ).name; | ||
var iterCuSomeBy = require( './../lib' ); | ||
|
||
|
||
// FUNCTIONS // | ||
|
||
/** | ||
* Predicate function. | ||
* | ||
* @private | ||
* @param {*} value - value | ||
* @returns {boolean} result | ||
*/ | ||
This comment has been minimized.
Sorry, something went wrong.
kgryte
Member
|
||
|
||
// MAIN // | ||
|
||
bench( pkg, function benchmark( b ) { | ||
var iter; | ||
var it; | ||
var i; | ||
|
||
function predicate( value ) { | ||
return ( value < 0 ); | ||
} | ||
|
||
it = iterConstant( 3.14 ); | ||
|
||
b.tic(); | ||
for ( i = 0; i < b.iterations; i++ ) { | ||
iter = iterCuSomeBy( it, 2, predicate ); | ||
if ( typeof iter !== 'object' ) { | ||
b.fail( 'should return an object' ); | ||
} | ||
} | ||
b.toc(); | ||
if ( !isIteratorLike( iter ) ) { | ||
b.fail( 'should return an iterator protocol-compliant object' ); | ||
} | ||
b.pass( 'benchmark finished' ); | ||
b.end(); | ||
}); | ||
|
||
bench( pkg+'::iteration', function benchmark( b ) { | ||
var iter; | ||
var v; | ||
var i; | ||
|
||
function predicate( value ) { | ||
return ( value < 0 ); | ||
} | ||
|
||
iter = iterCuSomeBy( iterConstant( 3.14 ), 2, predicate ); | ||
|
||
b.tic(); | ||
for ( i = 0; i < b.iterations; i++ ) { | ||
v = iter.next().value; | ||
if ( !isBoolean( v ) ) { | ||
b.fail( 'should return a boolean' ); | ||
} | ||
} | ||
b.toc(); | ||
if ( !isBoolean( v ) ) { | ||
b.fail( 'should return a boolean' ); | ||
} | ||
b.pass( 'benchmark finished' ); | ||
b.end(); | ||
}); |
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
@@ -0,0 +1,67 @@ | ||||
|
||||
{{alias}}( iterator, n, predicate[, thisArg] ) | ||||
Returns an iterator which cumulatively tests whether at least `n` iterated | ||||
values pass a test implemented by a predicate function. | ||||
|
||||
If an environment supports Symbol.iterator and a provided iterator is | ||||
iterable, the returned iterator is iterable. | ||||
|
||||
The predicate function is provided two arguments: | ||||
|
||||
- value: iterated value | ||||
- index: iteration index | ||||
|
||||
A predicate function is invoked for each iterated value until the n | ||||
This comment has been minimized.
Sorry, something went wrong. |
||||
truthy predicate function return value. Upon encountering the nth truthy | ||||
return value, the returned iterator ceases to invoke the predicate function | ||||
and returns `true` for each subsequent iterated value of the provided input | ||||
iterator. | ||||
|
||||
If provided an iterator which does not return any iterated values, the | ||||
function returns an iterator which is also empty. | ||||
|
||||
Parameters | ||||
---------- | ||||
iterator: Object | ||||
Input iterator. | ||||
|
||||
n: integer | ||||
Number of successful values to check for. | ||||
This comment has been minimized.
Sorry, something went wrong.
kgryte
Member
|
Minimum number of truthy values. |
2 comments
on commit fd271be
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Coverage Report
Package | Statements | Branches | Functions | Lines |
---|---|---|---|---|
iter/cusome-by |
|
|
|
|
The above coverage report was generated for the changes in this push.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Planeshifter We need to add additional tests to ensure 100% code coverage.
@Planeshifter This note differs from other similar packages such as
cuevery-by
andcuany-by
. I think it preferable to adopt the verbiage used in those packages. The second sentence here doesn't add much, given that this is a cumulative iterator.Also, for the first sentence, as
nth
isn't a variable name