Skip to content

Commit d71d044

Browse files
authored
feat: add sort method to array/bool
PR-URL: #2363 Ref: #2304 Reviewed-by: Athan Reines <[email protected]>
1 parent 1b80190 commit d71d044

File tree

6 files changed

+537
-0
lines changed

6 files changed

+537
-0
lines changed

Diff for: lib/node_modules/@stdlib/array/bool/README.md

+49
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,55 @@ A few notes:
481481
- If a target array cannot accommodate all values (i.e., the length of source array plus `i` exceeds the target array length), the method throws an error.
482482
- If provided a [typed array][@stdlib/array/typed] which shares an [`ArrayBuffer`][@stdlib/array/buffer] with the target array, the method will intelligently copy the source range to the destination range.
483483

484+
<a name="method-sort"></a>
485+
486+
#### BooleanArray.prototype.sort( \[compareFcn] )
487+
488+
Sorts an array in-place.
489+
490+
```javascript
491+
function compare( a, b ) {
492+
if ( a === false ) {
493+
if ( b === false ) {
494+
return 0;
495+
}
496+
return 1;
497+
}
498+
if ( b === true ) {
499+
return 0;
500+
}
501+
return -1;
502+
}
503+
504+
var arr = new BooleanArray( 3 );
505+
506+
arr.set( true, 0 );
507+
arr.set( false, 1 );
508+
arr.set( true, 2 );
509+
510+
arr.sort( compare );
511+
512+
var v = arr.get( 0 );
513+
// returns true
514+
515+
v = arr.get( 1 );
516+
// returns true
517+
518+
v = arr.get( 2 );
519+
// returns false
520+
```
521+
522+
The `compareFcn` determines the order of the elements. The function is called with the following arguments:
523+
524+
- **a**: the first boolean value for comparison.
525+
- **b**: the second boolean value for comparison.
526+
527+
The function should return a number where:
528+
529+
- a negative value indicates that `a` should come before `b`.
530+
- a positive value indicates that `a` should come after `b`.
531+
- zero or `NaN` indicates that `a` and `b` are considered equal.
532+
484533
</section>
485534

486535
<!-- /.usage -->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
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 isBooleanArray = require( '@stdlib/assert/is-booleanarray' );
25+
var pkg = require( './../package.json' ).name;
26+
var BooleanArray = require( './../lib' );
27+
28+
29+
// FUNCTIONS //
30+
31+
/**
32+
* Comparison function.
33+
*
34+
* @private
35+
* @param {boolean} a - first boolean value for comparison
36+
* @param {boolean} b - second boolean value for comparison
37+
* @returns {number} comparison result
38+
*/
39+
function compareFcn( a, b ) {
40+
if ( a === true ) {
41+
if ( b === true ) {
42+
return 0;
43+
}
44+
return 1;
45+
}
46+
if ( b === false ) {
47+
return 0;
48+
}
49+
return -1;
50+
}
51+
52+
53+
// MAIN //
54+
55+
bench( pkg+':sort', function benchmark( b ) {
56+
var out;
57+
var arr;
58+
var i;
59+
60+
arr = new BooleanArray( [ true, false, false, true, true, false ] );
61+
62+
b.tic();
63+
for ( i = 0; i < b.iterations; i++ ) {
64+
out = arr.sort( compareFcn );
65+
if ( typeof out !== 'object' ) {
66+
b.fail( 'should return an object' );
67+
}
68+
}
69+
b.toc();
70+
if ( !isBooleanArray( out ) ) {
71+
b.fail( 'should return a BooleanArray' );
72+
}
73+
b.pass( 'benchmark finished' );
74+
b.end();
75+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
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 Boolean = require( '@stdlib/boolean/ctor' );
25+
var isBooleanArray = require( '@stdlib/assert/is-booleanarray' );
26+
var pow = require( '@stdlib/math/base/special/pow' );
27+
var pkg = require( './../package.json' ).name;
28+
var BooleanArray = require( './../lib' );
29+
30+
31+
// FUNCTIONS //
32+
33+
/**
34+
* Comparison function.
35+
*
36+
* @private
37+
* @param {boolean} a - first boolean value for comparison
38+
* @param {boolean} b - second boolean value for comparison
39+
* @returns {number} comparison result
40+
*/
41+
function compareFcn( a, b ) {
42+
if ( a === true ) {
43+
if ( b === true ) {
44+
return 0;
45+
}
46+
return 1;
47+
}
48+
if ( b === false ) {
49+
return 0;
50+
}
51+
return -1;
52+
}
53+
54+
/**
55+
* Creates a benchmark function.
56+
*
57+
* @private
58+
* @param {PositiveInteger} len - array length
59+
* @returns {Function} benchmark function
60+
*/
61+
function createBenchmark( len ) {
62+
var arr;
63+
var i;
64+
65+
arr = [];
66+
for ( i = 0; i < len; i++ ) {
67+
arr.push( Boolean( i%2 ) );
68+
}
69+
arr = new BooleanArray( arr );
70+
71+
return benchmark;
72+
73+
/**
74+
* Benchmark function.
75+
*
76+
* @private
77+
* @param {Benchmark} b - benchmark instance
78+
*/
79+
function benchmark( b ) {
80+
var out;
81+
var i;
82+
83+
b.tic();
84+
for ( i = 0; i < b.iterations; i++ ) {
85+
out = arr.sort( compareFcn );
86+
if ( typeof out !== 'object' ) {
87+
b.fail( 'should return an object' );
88+
}
89+
}
90+
b.toc();
91+
if ( !isBooleanArray( out ) ) {
92+
b.fail( 'should return a BooleanArray' );
93+
}
94+
b.pass( 'benchmark finished' );
95+
b.end();
96+
}
97+
}
98+
99+
100+
// MAIN //
101+
102+
/**
103+
* Main execution sequence.
104+
*
105+
* @private
106+
*/
107+
function main() {
108+
var len;
109+
var min;
110+
var max;
111+
var f;
112+
var i;
113+
114+
min = 1; // 10^min
115+
max = 6; // 10^max
116+
117+
for ( i = min; i <= max; i++ ) {
118+
len = pow( 10, i );
119+
f = createBenchmark( len );
120+
bench( pkg+':sort:len='+len, f );
121+
}
122+
}
123+
124+
main();

Diff for: lib/node_modules/@stdlib/array/bool/docs/types/index.d.ts

+48
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,15 @@ type TernaryMapFcn<U> = ( this: U, value: boolean, index: number, arr: BooleanAr
106106
*/
107107
type MapFcn<U> = NullaryMapFcn<U> | UnaryMapFcn<U> | BinaryMapFcn<U> | TernaryMapFcn<U>;
108108

109+
/**
110+
* Comparator function.
111+
*
112+
* @param a - first boolean value for comparison
113+
* @param b - second boolean value for comparison
114+
* @returns number indicating comparison result
115+
*/
116+
type CompareFcn = ( a: boolean, b: boolean ) => number;
117+
109118
/**
110119
* Class for creating a Boolean array.
111120
*/
@@ -312,6 +321,45 @@ declare class BooleanArray implements BooleanArrayInterface {
312321
* // returns true
313322
*/
314323
set( value: ArrayLike<any> | any, i?: number ): void;
324+
325+
/**
326+
* Sorts an array in-place.
327+
*
328+
* @param compareFcn - comparison function
329+
* @returns sorted array
330+
*
331+
* @example
332+
* function compare( a, b ) {
333+
* if ( a === false ) {
334+
* if ( b === false ) {
335+
* return 0;
336+
* }
337+
* return 1;
338+
* }
339+
* if ( b === true ) {
340+
* return 0;
341+
* }
342+
* return -1;
343+
* }
344+
*
345+
* var arr = new BooleanArray( 3 );
346+
*
347+
* arr.set( true, 0 );
348+
* arr.set( false, 1 );
349+
* arr.set( true, 2 );
350+
*
351+
* arr.sort( compare );
352+
*
353+
* var v = arr.get( 0 );
354+
* // returns true
355+
*
356+
* v = arr.get( 1 );
357+
* // returns true
358+
*
359+
* v = arr.get( 2 );
360+
* // returns false
361+
*/
362+
sort( compareFcn: CompareFcn ): BooleanArray;
315363
}
316364

317365
/**

Diff for: lib/node_modules/@stdlib/array/bool/lib/main.js

+73
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,79 @@ setReadOnly( BooleanArray.prototype, 'set', function set( value ) {
661661
buf[ idx ] = ( value ) ? 1 : 0;
662662
});
663663

664+
/**
665+
* Sorts an array in-place.
666+
*
667+
* @name sort
668+
* @memberof BooleanArray.prototype
669+
* @type {Function}
670+
* @param {Function} [compareFcn] - comparison function
671+
* @throws {TypeError} `this` must be a boolean array
672+
* @throws {TypeError} first argument must be a function
673+
* @returns {BooleanArray} sorted array
674+
*
675+
* @example
676+
* function compare( a, b ) {
677+
* if ( a === false ) {
678+
* if ( b === false ) {
679+
* return 0;
680+
* }
681+
* return 1;
682+
* }
683+
* if ( b === true ) {
684+
* return 0;
685+
* }
686+
* return -1;
687+
* }
688+
*
689+
* var arr = new BooleanArray( 3 );
690+
*
691+
* arr.set( true, 0 );
692+
* arr.set( false, 1 );
693+
* arr.set( true, 2 );
694+
*
695+
* arr.sort( compare );
696+
*
697+
* var v = arr.get( 0 );
698+
* // returns true
699+
*
700+
* v = arr.get( 1 );
701+
* // returns true
702+
*
703+
* v = arr.get( 2 );
704+
* // returns false
705+
*
706+
*/
707+
setReadOnly( BooleanArray.prototype, 'sort', function sort( compareFcn ) {
708+
var buf;
709+
710+
if ( !isBooleanArray( this ) ) {
711+
throw new TypeError( 'invalid invocation. `this` is not a boolean array.' );
712+
}
713+
buf = this._buffer;
714+
if ( arguments.length === 0 ) {
715+
buf.sort();
716+
return this;
717+
}
718+
if ( !isFunction( compareFcn ) ) {
719+
throw new TypeError( format( 'invalid argument. First argument must be a function. Value: `%s`.', compareFcn ) );
720+
}
721+
buf.sort( compare );
722+
return this;
723+
724+
/**
725+
* Comparison function for sorting.
726+
*
727+
* @private
728+
* @param {boolean} a - first boolean value for comparison
729+
* @param {boolean} b - second boolean value for comparison
730+
* @returns {number} comparison result
731+
*/
732+
function compare( a, b ) {
733+
return compareFcn( Boolean( a ), Boolean( b ) );
734+
}
735+
});
736+
664737

665738
// EXPORTS //
666739

0 commit comments

Comments
 (0)