Skip to content

Commit 4cb1778

Browse files
feat: add object/some-own-by
Ref: #7374
1 parent c14d555 commit 4cb1778

File tree

10 files changed

+1069
-0
lines changed

10 files changed

+1069
-0
lines changed
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
<!--
2+
3+
@license Apache-2.0
4+
5+
Copyright (c) 2024 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+
# someOwnBy
22+
23+
> Test whether an object contains at least `n` own properties which pass a test implemented by 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 someOwnBy = require( '@stdlib/object/some-own-by' );
41+
```
42+
43+
#### someOwnBy( obj, n, predicate\[, thisArg ] )
44+
45+
Tests whether an `object` contains at least `n` own properties which pass a test implemented by a `predicate` function.
46+
47+
```javascript
48+
function isNegative( value ) {
49+
return ( value < 0 );
50+
}
51+
52+
var obj = {
53+
'a': 1,
54+
'b': -2,
55+
'c': 3,
56+
'd': -1
57+
};
58+
59+
var bool = someOwnBy( obj, 2, isNegative );
60+
// returns true
61+
```
62+
63+
Once the function finds `n` successful properties, the function **immediately** returns `true`.
64+
65+
```javascript
66+
function isPositive( value ) {
67+
if ( value < 0 ) {
68+
throw new Error( 'should never reach this line' );
69+
}
70+
return ( value > 0 );
71+
}
72+
73+
var obj = {
74+
'a': 1,
75+
'b': 2,
76+
'c': -3,
77+
'd': 4
78+
};
79+
80+
var bool = someOwnBy( obj, 2, isPositive );
81+
// returns true
82+
```
83+
84+
The invoked `function` is provided three arguments:
85+
86+
- **value**: object property value.
87+
- **key**: object property key.
88+
- **obj**: input object.
89+
90+
To set the function execution context, provide a `thisArg`.
91+
92+
```javascript
93+
function sum( value ) {
94+
this.sum += value;
95+
this.count += 1;
96+
return ( value < 0 );
97+
}
98+
99+
var obj = {
100+
'a': 1,
101+
'b': 2,
102+
'c': 3,
103+
'd': -5
104+
};
105+
106+
var context = {
107+
'sum': 0,
108+
'count': 0
109+
};
110+
111+
var bool = someOwnBy( obj, 1, sum, context );
112+
// returns true
113+
114+
var mean = context.sum / context.count;
115+
// returns 0.25
116+
```
117+
118+
</section>
119+
120+
<!-- /.usage -->
121+
122+
<!-- Package usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
123+
124+
<section class="notes">
125+
126+
## Notes
127+
128+
- An [`Object`][mdn-object] refers to a JavaScript object, which is a collection of properties. Each property is an association between a key (or name) and a value. The key can be a string or a symbol, and the value can be any JavaScript value, including functions and other objects
129+
130+
- If provided an empty `object`, the function returns `false`.
131+
132+
```javascript
133+
function alwaysTrue() {
134+
return true;
135+
}
136+
var bool = someOwnBy( {}, 1, alwaysTrue );
137+
// returns false
138+
```
139+
140+
- The function does **not** skip `undefined` elements.
141+
142+
<!-- eslint-disable no-sparse-arrays, stdlib/doctest-marker -->
143+
144+
```javascript
145+
function log( value, key ) {
146+
console.log( '%s: %s', key, value );
147+
return ( value < 0 );
148+
}
149+
150+
var obj = {
151+
'a': 1,
152+
'b': void 0,
153+
'c': void 0,
154+
'd': 4,
155+
'e': -1
156+
};
157+
158+
var bool = someOwnBy( obj, 1, log );
159+
/* =>
160+
a: 1
161+
b: void 0
162+
c: void 0
163+
d: 4
164+
e: -1
165+
*/
166+
```
167+
168+
- The function provides limited support for dynamic objects (i.e., objects whose `length` changes during execution).
169+
170+
</section>
171+
172+
<!-- /.notes -->
173+
174+
<!-- Package usage examples. -->
175+
176+
<section class="examples">
177+
178+
## Examples
179+
180+
<!-- eslint no-undef: "error" -->
181+
182+
```javascript
183+
var randu = require( '@stdlib/random/base/randu' );
184+
var someOwnBy = require( '@stdlib/object/some-own-by' );
185+
186+
function threshold( value ) {
187+
return ( value > 0.95 );
188+
}
189+
190+
var bool;
191+
var obj = {};
192+
var i;
193+
194+
for ( i = 0; i < 100; i++ ) {
195+
obj[ 'key'+i ] = randu();
196+
}
197+
198+
bool = someOwnBy( obj, 5, threshold );
199+
// returns <boolean>
200+
```
201+
202+
</section>
203+
204+
<!-- /.examples -->
205+
206+
<!-- 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. -->
207+
208+
<section class="references">
209+
210+
</section>
211+
212+
<!-- /.references -->
213+
214+
<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->
215+
216+
<section class="related">
217+
218+
* * *
219+
220+
## See Also
221+
222+
- <span class="package-name">[`@stdlib/utils/any-own-by`][@stdlib/utils/any-own-by]</span><span class="delimiter">: </span><span class="description">test whether whether any 'own' property of a provided object satisfies a predicate function.</span>
223+
- <span class="package-name">[`@stdlib/utils/every-own-by`][@stdlib/utils/every-own-by]</span><span class="delimiter">: </span><span class="description">test whether all own properties of an object pass a test implemented by a predicate function.</span>
224+
- <span class="package-name">[`@stdlib/utils/some-by`][@stdlib/utils/some-by]</span><span class="delimiter">: </span><span class="description">test whether a collection contains at least `n` elements which pass a test implemented by a predicate function.</span>
225+
- <span class="package-name">[`@stdlib/utils/some-in-by`][@stdlib/utils/some-in-by]</span><span class="delimiter">: </span><span class="description">test whether an object contains at least n properties (own and inherited) which pass a test implemented by a predicate function.</span>
226+
227+
</section>
228+
229+
<!-- /.related -->
230+
231+
<!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
232+
233+
<section class="links">
234+
235+
[mdn-object]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
236+
237+
<!-- <related-links> -->
238+
239+
[@stdlib/utils/any-own-by]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/utils/any-own-by
240+
241+
[@stdlib/utils/every-own-by]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/utils/every-own-by
242+
243+
[@stdlib/utils/some-by]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/utils/some-by
244+
245+
[@stdlib/utils/some-in-by]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/utils/some-in-by
246+
247+
<!-- </related-links> -->
248+
249+
</section>
250+
251+
<!-- /.links -->
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2024 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
'use strict';
20+
21+
// MODULES //
22+
23+
var bench = require( '@stdlib/bench' );
24+
var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive;
25+
var isnan = require( '@stdlib/math/base/assert/is-nan' );
26+
var pkg = require( './../package.json' ).name;
27+
var someOwnBy = require( './../lib' );
28+
29+
30+
// MAIN //
31+
32+
bench( pkg, function benchmark( b ) {
33+
var bool;
34+
var obj;
35+
var i;
36+
37+
function predicate( v ) {
38+
return isnan( v );
39+
}
40+
41+
b.tic();
42+
for ( i = 0; i < b.iterations; i++ ) {
43+
obj = {
44+
'a': i,
45+
'b': i+1,
46+
'c': i+2,
47+
'd': NaN,
48+
'e': i+4,
49+
'f': NaN
50+
};
51+
bool = someOwnBy( obj, 2, predicate );
52+
if ( typeof bool !== 'boolean' ) {
53+
b.fail( 'should return a boolean' );
54+
}
55+
}
56+
b.toc();
57+
if ( !isBoolean( bool ) ) {
58+
b.fail( 'should return a boolean' );
59+
}
60+
b.pass( 'benchmark finished' );
61+
b.end();
62+
});
63+
64+
bench( pkg+'::loop', function benchmark( b ) {
65+
var total;
66+
var count;
67+
var bool;
68+
var keys;
69+
var obj;
70+
var key;
71+
var i;
72+
var j;
73+
74+
total = 2;
75+
76+
b.tic();
77+
for ( i = 0; i < b.iterations; i++ ) {
78+
obj = {
79+
'a': i,
80+
'b': i+1,
81+
'c': i+2,
82+
'd': NaN,
83+
'e': i+4,
84+
'f': NaN
85+
};
86+
bool = false;
87+
count = 0;
88+
keys = Object.keys( obj );
89+
for ( j = 0; j < keys.length; j++ ) {
90+
key = keys[ j ];
91+
if ( isnan( obj[ key ] ) ) {
92+
count += 1;
93+
if ( count === total ) {
94+
bool = true;
95+
break;
96+
}
97+
}
98+
}
99+
if ( typeof bool !== 'boolean' ) {
100+
b.fail( 'should return a boolean' );
101+
}
102+
}
103+
b.toc();
104+
if ( !isBoolean( bool ) ) {
105+
b.fail( 'should be a boolean' );
106+
}
107+
b.pass( 'benchmark finished' );
108+
b.end();
109+
});

0 commit comments

Comments
 (0)