Skip to content

Commit 7fde12d

Browse files
committed
Auto-generated commit
1 parent 17dc074 commit 7fde12d

16 files changed

+454
-42
lines changed

index/docs/types/index.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ interface Constructor {
512512
* var dt = o.dtype;
513513
* // returns 'uint8'
514514
*/
515-
get( id: string ): ArrayObject;
515+
get<T extends BaseArrayObject = ArrayObject>( id: string ): T;
516516
}
517517

518518
/**

to-fancy/README.md

+114-18
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,19 @@ v = y[ ':' ];
113113

114114
The function supports the following options:
115115

116+
- **cache**: cache for resolving array index objects. Must have a `get` method which accepts a single argument: a string identifier associated with an array index.
117+
118+
If an array index associated with a provided identifier exists, the `get` method should return an object having the following properties:
119+
120+
- **data**: the underlying index array.
121+
- **type**: the index type. Must be either `'mask'`, `'bool'`, or `'int'`.
122+
- **dtype**: the [data type][@stdlib/array/dtypes] of the underlying array.
123+
124+
If an array index is not associated with a provided identifier, the `get` method should return `null`.
125+
126+
Default: [`ArrayIndex`][@stdlib/array/index].
127+
116128
- **strict**: boolean indicating whether to enforce strict bounds checking. Default: `false`.
117-
- **cache**: cache for resolving array index objects. Default: [`ArrayIndex`][@stdlib/array/index].
118129

119130
By default, the function returns a fancy array which does **not** enforce strict bounds checking. For example,
120131

@@ -156,8 +167,19 @@ var v = y[ ':' ];
156167

157168
The function supports the following options:
158169

170+
- **cache**: default cache for resolving array index objects. Must have a `get` method which accepts a single argument: a string identifier associated with an array index.
171+
172+
If an array index associated with a provided identifier exists, the `get` method should return an object having the following properties:
173+
174+
- **data**: the underlying index array.
175+
- **type**: the index type. Must be either `'mask'`, `'bool'`, or `'int'`.
176+
- **dtype**: the [data type][@stdlib/array/dtypes] of the underlying array.
177+
178+
If an array index is not associated with a provided identifier, the `get` method should return `null`.
179+
180+
Default: [`ArrayIndex`][@stdlib/array/index].
181+
159182
- **strict**: boolean indicating whether to enforce strict bounds checking by default. Default: `false`.
160-
- **cache**: cache for resolving array index objects. Default: [`ArrayIndex`][@stdlib/array/index].
161183

162184
By default, the function returns a function which, by default, does **not** enforce strict bounds checking. For example,
163185

@@ -205,6 +227,72 @@ The returned function supports the same options as above. When the returned func
205227
- Indexing expressions provide a convenient and powerful means for creating and operating on array views; however, their use does entail a performance cost. Indexing expressions are best suited for interactive use (e.g., in the [REPL][@stdlib/repl]) and scripting. For performance critical applications, prefer equivalent functional APIs supporting array-like objects.
206228
- In older JavaScript environments which do **not** support [`Proxy`][@stdlib/proxy/ctor] objects, the use of indexing expressions is **not** supported.
207229

230+
### Bounds Checking
231+
232+
By default, fancy arrays do **not** enforce strict bounds checking across index expressions. The motivation for the default fancy array behavior stems from a desire to maintain parity with plain arrays; namely, the returning of `undefined` when accessing a single non-existent property.
233+
234+
Accordingly, when `strict` is `false`, one may observe the following behaviors:
235+
236+
<!-- run throws: true -->
237+
238+
```javascript
239+
var idx = require( '@stdlib/array/index' );
240+
241+
var x = array2fancy( [ 1, 2, 3, 4 ], {
242+
'strict': false
243+
});
244+
245+
// Access a non-existent property:
246+
var v = x[ 'foo' ];
247+
// returns undefined
248+
249+
// Access an out-of-bounds index:
250+
v = x[ 10 ];
251+
// returns undefined
252+
253+
v = x[ -10 ];
254+
// returns undefined
255+
256+
// Access an out-of-bounds slice:
257+
v = x[ '10:' ];
258+
// returns []
259+
260+
// Access one or more out-of-bounds indices:
261+
v = x[ idx( [ 10, 20 ] ) ];
262+
// throws <RangeError>
263+
```
264+
265+
When `strict` is `true`, fancy arrays normalize index behavior and consistently enforce strict bounds checking.
266+
267+
<!-- run throws: true -->
268+
269+
```javascript
270+
var idx = require( '@stdlib/array/index' );
271+
272+
var x = array2fancy( [ 1, 2, 3, 4 ], {
273+
'strict': true
274+
});
275+
276+
// Access a non-existent property:
277+
var v = x[ 'foo' ];
278+
// returns undefined
279+
280+
// Access an out-of-bounds index:
281+
v = x[ 10 ];
282+
// throws <RangeError>
283+
284+
v = x[ -10 ];
285+
// throws <RangeError>
286+
287+
// Access an out-of-bounds slice:
288+
v = x[ '10:' ];
289+
// throws <RangeError>
290+
291+
// Access one or more out-of-bounds indices:
292+
v = x[ idx( [ 10, 20 ] ) ];
293+
// throws <RangeError>
294+
```
295+
208296
### Broadcasting
209297

210298
Fancy arrays support **broadcasting** in which assigned scalars and single-element arrays are repeated (without additional memory allocation) to match the length of a target array instance.
@@ -340,22 +428,6 @@ im = imag( v );
340428
// returns 0.0
341429
```
342430

343-
Note, however, that attempting to assign a real-valued array to a complex number array slice is **not** supported due to the ambiguity of whether the real-valued array is a collection of real components (with implied imaginary components equal to zero) or an array of interleaved real and imaginary components.
344-
345-
<!-- run throws: true -->
346-
347-
```javascript
348-
var Float64Array = require( '@stdlib/array/float64' );
349-
var Complex128Array = require( '@stdlib/array/complex128' );
350-
351-
var x = new Complex128Array( [ 1.0, 2.0, 3.0, 4.0 ] );
352-
var y = array2fancy( x );
353-
354-
// Attempt to assign a real-valued array:
355-
y[ ':' ] = new Float64Array( [ 5.0, 6.0 ] ); // is this a single complex number which should be broadcast or a list of real components with implied imaginary components?
356-
// throws <Error>
357-
```
358-
359431
</section>
360432

361433
<!-- /.notes -->
@@ -371,12 +443,16 @@ y[ ':' ] = new Float64Array( [ 5.0, 6.0 ] ); // is this a single complex number
371443
<!-- eslint no-undef: "error" -->
372444

373445
```javascript
446+
var Uint8Array = require( '@stdlib/array/uint8' );
447+
var Int32Array = require( '@stdlib/array/int32' );
448+
var idx = require( '@stdlib/array/index' );
374449
var array2fancy = require( '@stdlib/array/to-fancy' );
375450

376451
var x = [ 1, 2, 3, 4, 5, 6 ];
377452
var y = array2fancy( x );
378453
// returns <Array>
379454

455+
// Slice retrieval:
380456
var z = y[ '1::2' ];
381457
// returns [ 2, 4, 6 ]
382458

@@ -386,13 +462,31 @@ z = y[ '-2::-2' ];
386462
z = y[ '1:4' ];
387463
// returns [ 2, 3, 4 ]
388464

465+
// Slice assignment:
389466
y[ '4:1:-1' ] = 10;
390467
z = y[ ':' ];
391468
// returns [ 1, 2, 10, 10, 10, 6 ]
392469

393470
y[ '2:5' ] = [ -10, -9, -8 ];
394471
z = y[ ':' ];
395472
// returns [ 1, 2, -10, -9, -8, 6 ]
473+
474+
// Array index retrieval:
475+
var i = idx( [ 1, 3, 4 ] ); // integer index array
476+
z = y[ i ];
477+
// returns [ 2, -9, -8 ]
478+
479+
i = idx( [ true, false, false, true, true, true ] ); // boolean array
480+
z = y[ i ];
481+
// returns [ 1, -9, -8, 6 ]
482+
483+
i = idx( new Uint8Array( [ 0, 0, 1, 0, 0, 1 ] ) ); // mask array
484+
z = y[ i ];
485+
// returns [ 1, 2, -9, -8 ]
486+
487+
i = idx( new Int32Array( [ 0, 0, 1, 1, 2, 2 ] ) ); // integer index array
488+
z = y[ i ];
489+
// returns [ 1, 1, 2, 2, -10, -10 ]
396490
```
397491

398492
</section>
@@ -439,6 +533,8 @@ z = y[ ':' ];
439533

440534
[@stdlib/array/index]: https://github.com/stdlib-js/array/tree/main/index
441535

536+
[@stdlib/array/dtypes]: https://github.com/stdlib-js/array/tree/main/dtypes
537+
442538
</section>
443539

444540
<!-- /.links -->

to-fancy/docs/repl.txt

+8-12
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,6 @@
4848
scalar to a complex number argument having an imaginary component equal to
4949
zero.
5050

51-
Note, however, that attempting to assign a real-valued array to a complex
52-
number array slice is *not* supported due to the ambiguity of whether the
53-
real-valued array is a collection of real components (with implied imaginary
54-
components equal to zero) or an array of interleaved real and imaginary
55-
components.
56-
5751
In older JavaScript environments which do not support Proxy objects, the use
5852
of indexing expressions is not supported.
5953

@@ -71,9 +65,10 @@
7165

7266
options.cache: Object (optional)
7367
Cache for resolving array index objects. Must have a 'get' method which
74-
accepts a single argument: an identifier associated with an array index.
75-
If an array index associated with a provided identifier exists, the
76-
'get' method should return an object having the following properties:
68+
accepts a single argument: a string identifier associated with an array
69+
index. If an array index associated with a provided identifier exists,
70+
the 'get' method should return an object having the following
71+
properties:
7772

7873
- data: the underlying index array.
7974
- type: the index type. Must be either 'mask', 'bool', or 'int'.
@@ -111,9 +106,10 @@
111106

112107
options.cache: Object (optional)
113108
Cache for resolving array index objects. Must have a 'get' method which
114-
accepts a single argument: an identifier associated with an array index.
115-
If an array index associated with a provided identifier exists, the
116-
'get' method should return an object having the following properties:
109+
accepts a single argument: a string identifier associated with an array
110+
index. If an array index associated with a provided identifier exists,
111+
the 'get' method should return an object having the following
112+
properties:
117113

118114
- data: the underlying index array.
119115
- type: the index type. Must be either 'mask', 'bool', or 'int'.

to-fancy/examples/index.js

+26
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,16 @@
1818

1919
'use strict';
2020

21+
var Uint8Array = require( './../../uint8' );
22+
var Int32Array = require( './../../int32' );
23+
var idx = require( './../../index' );
2124
var array2fancy = require( './../lib' );
2225

2326
var x = [ 1, 2, 3, 4, 5, 6 ];
2427
var y = array2fancy( x );
2528
// returns <Array>
2629

30+
// Slice retrieval:
2731
var z = y[ '1::2' ];
2832
console.log( z );
2933
// => [ 2, 4, 6 ]
@@ -36,6 +40,7 @@ z = y[ '1:4' ];
3640
console.log( z );
3741
// => [ 2, 3, 4 ]
3842

43+
// Slice assignment:
3944
y[ '4:1:-1' ] = 10;
4045
z = y[ ':' ];
4146
console.log( z );
@@ -45,3 +50,24 @@ y[ '2:5' ] = [ -10, -9, -8 ];
4550
z = y[ ':' ];
4651
console.log( z );
4752
// => [ 1, 2, -10, -9, -8, 6 ]
53+
54+
// Array index retrieval:
55+
var i = idx( [ 1, 3, 4 ] ); // integer index array
56+
z = y[ i ];
57+
console.log( z );
58+
// => [ 2, -9, -8 ]
59+
60+
i = idx( [ true, false, false, true, true, true ] ); // boolean array
61+
z = y[ i ];
62+
console.log( z );
63+
// => [ 1, -9, -8, 6 ]
64+
65+
i = idx( new Uint8Array( [ 0, 0, 1, 0, 0, 1 ] ) ); // mask array
66+
z = y[ i ];
67+
console.log( z );
68+
// => [ 1, 2, -9, -8 ]
69+
70+
i = idx( new Int32Array( [ 0, 0, 1, 1, 2, 2 ] ) ); // integer index array
71+
z = y[ i ];
72+
console.log( z );
73+
// => [ 1, 1, 2, 2, -10, -10 ]

to-fancy/lib/factory.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ var arraylike2object = require( './../../base/arraylike2object' );
2626
var assign = require( '@stdlib/object/assign' );
2727
var format = require( '@stdlib/string/format' );
2828
var setElementWrapper = require( './set_element_wrapper.js' );
29-
var getSliceWrapper = require( './get_slice_wrapper.js' );
29+
var getArrayWrapper = require( './get_array_wrapper.js' );
3030
var hasProxySupport = require( './has_proxy_support.js' );
3131
var defaults = require( './defaults.js' );
3232
var validate = require( './validate.js' );
@@ -143,7 +143,7 @@ function factory() {
143143
'getter': arr.accessors[ 0 ],
144144
'setter': arr.accessors[ 1 ],
145145
'preSetElement': setElementWrapper( dt ),
146-
'postGetSlice': getSliceWrapper( array2fancy, opts ),
146+
'postGetArray': getArrayWrapper( array2fancy, opts ),
147147
'cache': opts.cache,
148148
'strict': opts.strict,
149149
'validator': validator( dt ),

to-fancy/lib/get.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
var isString = require( '@stdlib/assert/is-string' ).isPrimitive;
2424
var hasProperty = require( '@stdlib/assert/has-property' );
2525
var isIntegerString = require( './is_integer_string.js' );
26+
var isArrayIndexString = require( './is_array_index_string.js' );
27+
var getElements = require( './get_elements.js' );
2628
var getElement = require( './get_element.js' );
2729
var getValue = require( './get_value.js' );
2830
var getSlice = require( './get_slice.js' );
@@ -38,7 +40,8 @@ var getSlice = require( './get_slice.js' );
3840
* @param {Function} ctx.getter - accessor for retrieving array elements
3941
* @param {boolean} ctx.strict - boolean indicating whether to enforce strict bounds checking
4042
* @param {Function} ctx.ctor - proxied array constructor
41-
* @param {Function} ctx.postGetSlice - function to process a retrieved slice
43+
* @param {Function} ctx.postGetArray - function to process a retrieved array
44+
* @param {Object} ctx.cache - cache for resolving array index objects
4245
* @returns {Function} handler
4346
*/
4447
function factory( ctx ) {
@@ -53,6 +56,7 @@ function factory( ctx ) {
5356
* @param {Object} receiver - the proxy object or an object inheriting from the proxy
5457
* @throws {Error} invalid slice operation
5558
* @throws {RangeError} slice exceeds array bounds
59+
* @throws {RangeError} index exceeds array bounds
5660
* @returns {*} result
5761
*/
5862
function get( target, property, receiver ) {
@@ -62,7 +66,10 @@ function factory( ctx ) {
6266
if ( hasProperty( target, property ) || !isString( property ) ) {
6367
return getValue( target, property, receiver, ctx );
6468
}
65-
return getSlice( target, property, receiver, ctx );
69+
if ( isArrayIndexString( property ) ) {
70+
return getElements( target, property, ctx );
71+
}
72+
return getSlice( target, property, ctx );
6673
}
6774
}
6875

to-fancy/lib/get_slice_wrapper.js renamed to to-fancy/lib/get_array_wrapper.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,13 @@
2121
// MAIN //
2222

2323
/**
24-
* Returns a wrapper function for processing slices after retrieval.
24+
* Returns a wrapper function for processing arrays after retrieval.
2525
*
2626
* @private
2727
* @param {Function} array2fancy - function for creating a proxied array
2828
* @param {Object} opts - options
2929
* @param {boolean} opts.strict - boolean indicating whether to perform strict bounds checking
30+
* @param {Function} opts.cache - cache for resolving array index objects
3031
* @returns {Function} wrapper function
3132
*/
3233
function wrapper( array2fancy, opts ) {

0 commit comments

Comments
 (0)