@stdlib/dstructs-named-typed-tuple 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +177 -0
- package/NOTICE +1 -0
- package/README.md +2402 -0
- package/SECURITY.md +5 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +7 -0
- package/docs/types/index.d.ts +1529 -0
- package/lib/ascending.js +44 -0
- package/lib/contains.js +44 -0
- package/lib/from_iterator.js +48 -0
- package/lib/from_iterator_map.js +54 -0
- package/lib/has_distinct_elements.js +52 -0
- package/lib/index.js +53 -0
- package/lib/main.js +1444 -0
- package/lib/validate.js +84 -0
- package/package.json +93 -0
package/lib/main.js
ADDED
|
@@ -0,0 +1,1444 @@
|
|
|
1
|
+
/* eslint-disable max-len, max-lines */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*
|
|
6
|
+
* Copyright (c) 2018 The Stdlib Authors.
|
|
7
|
+
*
|
|
8
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
9
|
+
* you may not use this file except in compliance with the License.
|
|
10
|
+
* You may obtain a copy of the License at
|
|
11
|
+
*
|
|
12
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
*
|
|
14
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
15
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
16
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
17
|
+
* See the License for the specific language governing permissions and
|
|
18
|
+
* limitations under the License.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
'use strict';
|
|
22
|
+
|
|
23
|
+
// MODULES //
|
|
24
|
+
|
|
25
|
+
var isStringArray = require( '@stdlib/assert-is-string-array' ).primitives;
|
|
26
|
+
var isEmptyArrayLikeObject = require( '@stdlib/assert-is-empty-array-like-object' );
|
|
27
|
+
var isString = require( '@stdlib/assert-is-string' ).isPrimitive;
|
|
28
|
+
var isArrayBuffer = require( '@stdlib/assert-is-arraybuffer' );
|
|
29
|
+
var isFunction = require( '@stdlib/assert-is-function' );
|
|
30
|
+
var isInteger = require( '@stdlib/assert-is-integer' ).isPrimitive;
|
|
31
|
+
var isObject = require( '@stdlib/assert-is-object' );
|
|
32
|
+
var isCollection = require( '@stdlib/assert-is-collection' );
|
|
33
|
+
var hasOwnProp = require( '@stdlib/assert-has-own-property' );
|
|
34
|
+
var hasIteratorSymbolSupport = require( '@stdlib/assert-has-iterator-symbol-support' );
|
|
35
|
+
var propertiesIn = require( '@stdlib/utils-properties-in' );
|
|
36
|
+
var typedarray = require( '@stdlib/array-typed' );
|
|
37
|
+
var Int8Array = require( '@stdlib/array-int8' );
|
|
38
|
+
var getDtype = require( '@stdlib/array-dtype' );
|
|
39
|
+
var defineProperty = require( '@stdlib/utils-define-property' );
|
|
40
|
+
var setNonEnumerableProperty = require( '@stdlib/utils-define-nonenumerable-property' );
|
|
41
|
+
var setNonEnumerableReadOnlyAccessor = require( '@stdlib/utils-define-nonenumerable-read-only-accessor' ); // eslint-disable-line id-length
|
|
42
|
+
var setNonEnumerableReadWriteAccessor = require( '@stdlib/utils-define-nonenumerable-read-write-accessor' ); // eslint-disable-line id-length
|
|
43
|
+
var floor = require( '@stdlib/math-base-special-floor' );
|
|
44
|
+
var ITERATOR_SYMBOL = require( '@stdlib/symbol-iterator' );
|
|
45
|
+
var format = require( '@stdlib/string-format' );
|
|
46
|
+
var contains = require( './contains.js' );
|
|
47
|
+
var hasDistinctElements = require( './has_distinct_elements.js' );
|
|
48
|
+
var validate = require( './validate.js' );
|
|
49
|
+
var ascending = require( './ascending.js' );
|
|
50
|
+
var fromIterator = require( './from_iterator.js' );
|
|
51
|
+
var fromIteratorMap = require( './from_iterator_map.js' );
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
// VARIABLES //
|
|
55
|
+
|
|
56
|
+
var RESERVED_PROPS = propertiesIn( new Int8Array( 0 ) );
|
|
57
|
+
var HAS_ITERATOR_SYMBOL = hasIteratorSymbolSupport();
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
// MAIN //
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Returns a named typed tuple factory.
|
|
64
|
+
*
|
|
65
|
+
* @param {StringArray} names - field (property) names
|
|
66
|
+
* @param {Options} [options] - options
|
|
67
|
+
* @param {string} [options.dtype="float64"] - default data type
|
|
68
|
+
* @param {string} [options.name="tuple"] - tuple name
|
|
69
|
+
* @throws {TypeError} must provide an array of strings
|
|
70
|
+
* @throws {TypeError} must provide distinct field names
|
|
71
|
+
* @throws {Error} cannot provide a reserved field (property) name
|
|
72
|
+
* @throws {TypeError} must provide valid options
|
|
73
|
+
* @throws {Error} must provide a recognized data type
|
|
74
|
+
* @returns {Function} factory function
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* var point = factory( [ 'x', 'y' ] );
|
|
78
|
+
*
|
|
79
|
+
* var p = point( [ 1.0, -1.0 ] );
|
|
80
|
+
*
|
|
81
|
+
* var x = p[ 0 ];
|
|
82
|
+
* // returns 1.0
|
|
83
|
+
*
|
|
84
|
+
* x = p.x;
|
|
85
|
+
* // returns 1.0
|
|
86
|
+
*
|
|
87
|
+
* var y = p[ 1 ];
|
|
88
|
+
* // returns -1.0
|
|
89
|
+
*
|
|
90
|
+
* y = p.y;
|
|
91
|
+
* // returns -1.0
|
|
92
|
+
*/
|
|
93
|
+
function factory( names, options ) { // eslint-disable-line max-lines-per-function, stdlib/jsdoc-require-throws-tags
|
|
94
|
+
var nfields;
|
|
95
|
+
var fields;
|
|
96
|
+
var opts;
|
|
97
|
+
var err;
|
|
98
|
+
var i;
|
|
99
|
+
if ( !isStringArray( names ) && !isEmptyArrayLikeObject( names ) ) {
|
|
100
|
+
throw new TypeError( format( 'invalid argument. Must provide an array of strings. Value: `%s`.', names ) );
|
|
101
|
+
}
|
|
102
|
+
if ( !hasDistinctElements( names ) ) {
|
|
103
|
+
throw new TypeError( format( 'invalid argument. Field names must be distinct. Value: `%s`.', names ) );
|
|
104
|
+
}
|
|
105
|
+
fields = names.slice();
|
|
106
|
+
nfields = fields.length;
|
|
107
|
+
for ( i = 0; i < nfields; i++ ) {
|
|
108
|
+
if ( contains( RESERVED_PROPS, fields[ i ] ) ) {
|
|
109
|
+
throw new Error( format( 'invalid argument. Provided field name is reserved. Name: `%s`.', fields[ i ] ) );
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
opts = {
|
|
113
|
+
'dtype': 'float64',
|
|
114
|
+
'name': 'tuple'
|
|
115
|
+
};
|
|
116
|
+
if ( arguments.length > 1 ) {
|
|
117
|
+
err = validate( opts, options );
|
|
118
|
+
if ( err ) {
|
|
119
|
+
throw err;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Returns a named typed tuple.
|
|
125
|
+
*
|
|
126
|
+
* @private
|
|
127
|
+
* @param {(TypedArray|ArrayLikeObject|ArrayBuffer|Iterable)} [arg] - a typed array, array-like object, buffer, or an iterable
|
|
128
|
+
* @param {NonNegativeInteger} [byteOffset=0] - byte offset
|
|
129
|
+
* @param {string} [dtype] - data type
|
|
130
|
+
* @throws {TypeError} must provide a recognized data type
|
|
131
|
+
* @throws {RangeError} arguments must be compatible with tuple length
|
|
132
|
+
* @returns {TypedArray} named typed tuple
|
|
133
|
+
*/
|
|
134
|
+
function namedtypedtuple() { // eslint-disable-line max-lines-per-function
|
|
135
|
+
var indices;
|
|
136
|
+
var dtype;
|
|
137
|
+
var nargs;
|
|
138
|
+
var tuple;
|
|
139
|
+
var i;
|
|
140
|
+
|
|
141
|
+
nargs = arguments.length;
|
|
142
|
+
if ( nargs <= 0 ) {
|
|
143
|
+
tuple = typedarray( nfields, opts.dtype );
|
|
144
|
+
} else if ( nargs === 1 ) {
|
|
145
|
+
if ( isString( arguments[ 0 ] ) ) {
|
|
146
|
+
// Arguments: [ dtype ]
|
|
147
|
+
tuple = typedarray( nfields, arguments[ 0 ] );
|
|
148
|
+
} else if ( isArrayBuffer( arguments[ 0 ] ) ) {
|
|
149
|
+
// Arguments: [ ArrayBuffer ]
|
|
150
|
+
tuple = typedarray( arguments[ 0 ], 0, nfields, opts.dtype );
|
|
151
|
+
} else {
|
|
152
|
+
// Arguments: [ TypedArray|ArrayLikeObject|Iterable ]
|
|
153
|
+
tuple = typedarray( arguments[ 0 ], opts.dtype );
|
|
154
|
+
}
|
|
155
|
+
} else if ( nargs === 2 ) {
|
|
156
|
+
if ( isArrayBuffer( arguments[ 0 ] ) ) {
|
|
157
|
+
if ( isString( arguments[ 1 ] ) ) {
|
|
158
|
+
// Arguments: [ ArrayBuffer, dtype ]
|
|
159
|
+
tuple = typedarray( arguments[ 0 ], 0, nfields, arguments[ 1 ] );
|
|
160
|
+
} else {
|
|
161
|
+
// Arguments: [ ArrayBuffer, byteOffset ]
|
|
162
|
+
tuple = typedarray( arguments[ 0 ], arguments[ 1 ], nfields, opts.dtype );
|
|
163
|
+
}
|
|
164
|
+
} else {
|
|
165
|
+
// Arguments: [ TypedArray|ArrayLikeObject|Iterable, dtype ]
|
|
166
|
+
tuple = typedarray( arguments[ 0 ], arguments[ 1 ] );
|
|
167
|
+
}
|
|
168
|
+
} else {
|
|
169
|
+
// Arguments: [ ArrayBuffer, byteOffset, dtype ]
|
|
170
|
+
tuple = typedarray( arguments[ 0 ], arguments[ 1 ], nfields, arguments[ 2 ] );
|
|
171
|
+
}
|
|
172
|
+
if ( tuple.length !== nfields ) {
|
|
173
|
+
throw new RangeError( format( 'invalid arguments. Arguments are incompatible with the number of tuple fields. Number of fields: `%u`. Number of data elements: `%u`.', nfields, tuple.length ) );
|
|
174
|
+
}
|
|
175
|
+
dtype = getDtype( tuple );
|
|
176
|
+
|
|
177
|
+
indices = []; // indirect index look-up table
|
|
178
|
+
for ( i = 0; i < nfields; i++ ) {
|
|
179
|
+
indices.push( i );
|
|
180
|
+
setNonEnumerableReadWriteAccessor( tuple, fields[ i ], getter( i ), setter( i ) );
|
|
181
|
+
}
|
|
182
|
+
setNonEnumerableProperty( tuple, 'name', opts.name );
|
|
183
|
+
setNonEnumerableReadOnlyAccessor( tuple, 'fields', getFields );
|
|
184
|
+
setNonEnumerableReadOnlyAccessor( tuple, 'orderedFields', orderedFields );
|
|
185
|
+
|
|
186
|
+
// Note: keep in alphabetical order
|
|
187
|
+
setNonEnumerableProperty( tuple, 'entries', entries );
|
|
188
|
+
setNonEnumerableProperty( tuple, 'every', every );
|
|
189
|
+
setNonEnumerableProperty( tuple, 'fieldOf', fieldOf );
|
|
190
|
+
setNonEnumerableProperty( tuple, 'filter', filter );
|
|
191
|
+
setNonEnumerableProperty( tuple, 'find', find );
|
|
192
|
+
setNonEnumerableProperty( tuple, 'findIndex', findIndex );
|
|
193
|
+
setNonEnumerableProperty( tuple, 'findField', findField );
|
|
194
|
+
setNonEnumerableProperty( tuple, 'forEach', forEach );
|
|
195
|
+
setNonEnumerableProperty( tuple, 'ind2key', ind2key );
|
|
196
|
+
setNonEnumerableProperty( tuple, 'key2ind', key2ind );
|
|
197
|
+
setNonEnumerableProperty( tuple, 'keys', keys );
|
|
198
|
+
setNonEnumerableProperty( tuple, 'lastFieldOf', lastFieldOf );
|
|
199
|
+
setNonEnumerableProperty( tuple, 'map', map );
|
|
200
|
+
setNonEnumerableProperty( tuple, 'reduce', reduce );
|
|
201
|
+
setNonEnumerableProperty( tuple, 'reduceRight', reduceRight );
|
|
202
|
+
setNonEnumerableProperty( tuple, 'reverse', reverse );
|
|
203
|
+
setNonEnumerableProperty( tuple, 'slice', slice );
|
|
204
|
+
setNonEnumerableProperty( tuple, 'some', some );
|
|
205
|
+
setNonEnumerableProperty( tuple, 'sort', sort );
|
|
206
|
+
setNonEnumerableProperty( tuple, 'subtuple', subtuple );
|
|
207
|
+
setNonEnumerableProperty( tuple, 'toJSON', toJSON );
|
|
208
|
+
setNonEnumerableProperty( tuple, 'toLocaleString', toLocaleString );
|
|
209
|
+
setNonEnumerableProperty( tuple, 'toString', toString );
|
|
210
|
+
|
|
211
|
+
return tuple;
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Returns an accessor to retrieve a tuple value.
|
|
215
|
+
*
|
|
216
|
+
* @private
|
|
217
|
+
* @param {NonNegativeInteger} i - tuple index
|
|
218
|
+
* @returns {Function} accessor
|
|
219
|
+
*/
|
|
220
|
+
function getter( i ) {
|
|
221
|
+
return get;
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Returns a tuple value.
|
|
225
|
+
*
|
|
226
|
+
* @private
|
|
227
|
+
* @returns {number} tuple value
|
|
228
|
+
*/
|
|
229
|
+
function get() {
|
|
230
|
+
return tuple[ indices[ i ] ];
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Returns an accessor to set a tuple value.
|
|
236
|
+
*
|
|
237
|
+
* @private
|
|
238
|
+
* @param {NonNegativeInteger} i - tuple index
|
|
239
|
+
* @returns {Function} accessor
|
|
240
|
+
*/
|
|
241
|
+
function setter( i ) {
|
|
242
|
+
return set;
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Sets a tuple value.
|
|
246
|
+
*
|
|
247
|
+
* @private
|
|
248
|
+
* @param {number} v - value to set
|
|
249
|
+
*/
|
|
250
|
+
function set( v ) {
|
|
251
|
+
tuple[ indices[ i ] ] = v;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Returns the list of tuple fields in index order.
|
|
257
|
+
*
|
|
258
|
+
* @private
|
|
259
|
+
* @memberof tuple
|
|
260
|
+
* @returns {StringArray} tuple fields
|
|
261
|
+
*/
|
|
262
|
+
function orderedFields() {
|
|
263
|
+
var out;
|
|
264
|
+
var i;
|
|
265
|
+
out = fields.slice();
|
|
266
|
+
for ( i = 0; i < nfields; i++ ) {
|
|
267
|
+
out[ i ] = fields[ indices[i] ];
|
|
268
|
+
}
|
|
269
|
+
return out;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Note: keep functions which follow in alphabetical order
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Returns an iterator for iterating over tuple key-value pairs.
|
|
276
|
+
*
|
|
277
|
+
* @private
|
|
278
|
+
* @memberof tuple
|
|
279
|
+
* @throws {TypeError} `this` must be the host tuple
|
|
280
|
+
* @returns {Iterator} iterator
|
|
281
|
+
*/
|
|
282
|
+
function entries() {
|
|
283
|
+
var self;
|
|
284
|
+
var iter;
|
|
285
|
+
var FLG;
|
|
286
|
+
var i;
|
|
287
|
+
|
|
288
|
+
self = this; // eslint-disable-line no-invalid-this
|
|
289
|
+
if ( self !== tuple ) {
|
|
290
|
+
throw new TypeError( 'invalid invocation. `this` is not host tuple.' );
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Initialize the iteration index:
|
|
294
|
+
i = -1;
|
|
295
|
+
|
|
296
|
+
// Create an iterator protocol-compliant object:
|
|
297
|
+
iter = {};
|
|
298
|
+
defineProperty( iter, 'next', {
|
|
299
|
+
'configurable': false,
|
|
300
|
+
'enumerable': false,
|
|
301
|
+
'writable': false,
|
|
302
|
+
'value': next
|
|
303
|
+
});
|
|
304
|
+
defineProperty( iter, 'return', {
|
|
305
|
+
'configurable': false,
|
|
306
|
+
'enumerable': false,
|
|
307
|
+
'writable': false,
|
|
308
|
+
'value': end
|
|
309
|
+
});
|
|
310
|
+
if ( HAS_ITERATOR_SYMBOL ) {
|
|
311
|
+
defineProperty( iter, ITERATOR_SYMBOL, {
|
|
312
|
+
'configurable': false,
|
|
313
|
+
'enumerable': false,
|
|
314
|
+
'writable': false,
|
|
315
|
+
'value': factory
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
return iter;
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Returns an iterator protocol-compliant object containing the next iterated value.
|
|
322
|
+
*
|
|
323
|
+
* @private
|
|
324
|
+
* @returns {Object} iterator protocol-compliant object
|
|
325
|
+
*/
|
|
326
|
+
function next() {
|
|
327
|
+
i += 1;
|
|
328
|
+
if ( FLG || i >= nfields ) {
|
|
329
|
+
return {
|
|
330
|
+
'done': true
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
return {
|
|
334
|
+
'value': [ i, fields[ indices[ i ] ], tuple[ i ] ],
|
|
335
|
+
'done': false
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Finishes an iterator.
|
|
341
|
+
*
|
|
342
|
+
* @private
|
|
343
|
+
* @param {*} [value] - value to return
|
|
344
|
+
* @returns {Object} iterator protocol-compliant object
|
|
345
|
+
*/
|
|
346
|
+
function end( value ) {
|
|
347
|
+
FLG = true;
|
|
348
|
+
if ( arguments.length ) {
|
|
349
|
+
return {
|
|
350
|
+
'value': value,
|
|
351
|
+
'done': true
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
return {
|
|
355
|
+
'done': true
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Returns a new iterator.
|
|
361
|
+
*
|
|
362
|
+
* @private
|
|
363
|
+
* @returns {Iterator} iterator
|
|
364
|
+
*/
|
|
365
|
+
function factory() {
|
|
366
|
+
return self.entries();
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Tests whether all tuple elements pass a test implemented by a predicate function.
|
|
372
|
+
*
|
|
373
|
+
* @private
|
|
374
|
+
* @memberof tuple
|
|
375
|
+
* @param {Function} predicate - predicate function
|
|
376
|
+
* @param {*} [thisArg] - execution context
|
|
377
|
+
* @throws {TypeError} `this` must be the host tuple
|
|
378
|
+
* @throws {TypeError} first argument must be a function
|
|
379
|
+
* @returns {boolean} boolean indicating if all elements pass
|
|
380
|
+
*/
|
|
381
|
+
function every( predicate, thisArg ) {
|
|
382
|
+
var bool;
|
|
383
|
+
var i;
|
|
384
|
+
if ( this !== tuple ) { // eslint-disable-line no-invalid-this
|
|
385
|
+
throw new TypeError( 'invalid invocation. `this` is not host tuple.' );
|
|
386
|
+
}
|
|
387
|
+
if ( !isFunction( predicate ) ) {
|
|
388
|
+
throw new TypeError( format( 'invalid argument. First argument must be a function. Value: `%s`.', predicate ) );
|
|
389
|
+
}
|
|
390
|
+
for ( i = 0; i < nfields; i++ ) {
|
|
391
|
+
bool = predicate.call( thisArg, tuple[ i ], i, fields[ indices[i] ], tuple );
|
|
392
|
+
if ( !bool ) {
|
|
393
|
+
return false;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
return true;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Returns the field of the first tuple element strictly equal to a search element.
|
|
401
|
+
*
|
|
402
|
+
* ## Notes
|
|
403
|
+
*
|
|
404
|
+
* - The function does not distinguish between signed and unsigned zero.
|
|
405
|
+
* - If unable to locate a search element, the function returns `undefined`.
|
|
406
|
+
*
|
|
407
|
+
* @private
|
|
408
|
+
* @memberof tuple
|
|
409
|
+
* @param {*} searchElement - search element
|
|
410
|
+
* @param {integer} [fromIndex=0] - tuple index from which to begin searching
|
|
411
|
+
* @throws {TypeError} `this` must be the host tuple
|
|
412
|
+
* @throws {TypeError} second argument must be an integer
|
|
413
|
+
* @returns {(string|void)} tuple field name or `undefined`
|
|
414
|
+
*/
|
|
415
|
+
function fieldOf( searchElement ) {
|
|
416
|
+
var i;
|
|
417
|
+
if ( this !== tuple ) { // eslint-disable-line no-invalid-this
|
|
418
|
+
throw new TypeError( 'invalid invocation. `this` is not host tuple.' );
|
|
419
|
+
}
|
|
420
|
+
if ( arguments.length > 1 ) {
|
|
421
|
+
i = arguments[ 0 ];
|
|
422
|
+
if ( !isInteger( i ) ) {
|
|
423
|
+
throw new TypeError( format( 'invalid argument. Second argument must be an integer. Value: `%s`.', i ) );
|
|
424
|
+
}
|
|
425
|
+
if ( i >= nfields ) {
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
if ( i < 0 ) {
|
|
429
|
+
i = nfields + i;
|
|
430
|
+
if ( i < 0 ) {
|
|
431
|
+
i = 0;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
} else {
|
|
435
|
+
i = 0;
|
|
436
|
+
}
|
|
437
|
+
for ( ; i < nfields; i++ ) {
|
|
438
|
+
if ( tuple[ i ] === searchElement ) {
|
|
439
|
+
return fields[ indices[ i ] ];
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* Creates a new tuple which includes those elements for which a predicate function returns a truthy value.
|
|
446
|
+
*
|
|
447
|
+
* ## Notes
|
|
448
|
+
*
|
|
449
|
+
* - The returned tuple has the same data type as the host tuple.
|
|
450
|
+
* - If a predicate function does not return a truthy value for any tuple element, the function returns `null`.
|
|
451
|
+
*
|
|
452
|
+
* @private
|
|
453
|
+
* @memberof tuple
|
|
454
|
+
* @param {Function} predicate - filter (predicate) function
|
|
455
|
+
* @param {*} [thisArg] - execution context
|
|
456
|
+
* @throws {TypeError} `this` must be the host tuple
|
|
457
|
+
* @throws {TypeError} first argument must be a function
|
|
458
|
+
* @returns {(TypedArray|null)} new tuple
|
|
459
|
+
*/
|
|
460
|
+
function filter( predicate, thisArg ) {
|
|
461
|
+
var bool;
|
|
462
|
+
var tmp;
|
|
463
|
+
var f;
|
|
464
|
+
var i;
|
|
465
|
+
if ( this !== tuple ) { // eslint-disable-line no-invalid-this
|
|
466
|
+
throw new TypeError( 'invalid invocation. `this` is not host tuple.' );
|
|
467
|
+
}
|
|
468
|
+
if ( !isFunction( predicate ) ) {
|
|
469
|
+
throw new TypeError( format( 'invalid argument. First argument must be a function. Value: `%s`.', predicate ) );
|
|
470
|
+
}
|
|
471
|
+
tmp = [];
|
|
472
|
+
f = [];
|
|
473
|
+
for ( i = 0; i < nfields; i++ ) {
|
|
474
|
+
bool = predicate.call( thisArg, tuple[ i ], i, fields[ indices[i] ], tuple );
|
|
475
|
+
if ( bool ) {
|
|
476
|
+
f.push( fields[ indices[i] ] );
|
|
477
|
+
tmp.push( tuple[ i ] );
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
if ( f.length === nfields ) {
|
|
481
|
+
return namedtypedtuple( tmp, dtype );
|
|
482
|
+
}
|
|
483
|
+
if ( f.length ) {
|
|
484
|
+
return factory( f, opts )( tmp );
|
|
485
|
+
}
|
|
486
|
+
return null;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Returns the first tuple element for which a provided predicate function returns a truthy value.
|
|
491
|
+
*
|
|
492
|
+
* @private
|
|
493
|
+
* @memberof tuple
|
|
494
|
+
* @param {Function} predicate - predicate function
|
|
495
|
+
* @param {*} [thisArg] - execution context
|
|
496
|
+
* @throws {TypeError} `this` must be the host tuple
|
|
497
|
+
* @throws {TypeError} first argument must be a function
|
|
498
|
+
* @returns {(number|void)} tuple element
|
|
499
|
+
*/
|
|
500
|
+
function find( predicate, thisArg ) {
|
|
501
|
+
var bool;
|
|
502
|
+
var i;
|
|
503
|
+
if ( this !== tuple ) { // eslint-disable-line no-invalid-this
|
|
504
|
+
throw new TypeError( 'invalid invocation. `this` is not host tuple.' );
|
|
505
|
+
}
|
|
506
|
+
if ( !isFunction( predicate ) ) {
|
|
507
|
+
throw new TypeError( format( 'invalid argument. First argument must be a function. Value: `%s`.', predicate ) );
|
|
508
|
+
}
|
|
509
|
+
for ( i = 0; i < nfields; i++ ) {
|
|
510
|
+
bool = predicate.call( thisArg, tuple[ i ], i, fields[ indices[i] ], tuple );
|
|
511
|
+
if ( bool ) {
|
|
512
|
+
return tuple[ i ];
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* Returns the field of the first tuple element for which a provided predicate function returns a truthy value.
|
|
519
|
+
*
|
|
520
|
+
* ## Notes
|
|
521
|
+
*
|
|
522
|
+
* - If the predicate function never returns a truthy value, the function returns `undefined`.
|
|
523
|
+
*
|
|
524
|
+
* @private
|
|
525
|
+
* @memberof tuple
|
|
526
|
+
* @param {Function} predicate - predicate function
|
|
527
|
+
* @param {*} [thisArg] - execution context
|
|
528
|
+
* @throws {TypeError} `this` must be the host tuple
|
|
529
|
+
* @throws {TypeError} first argument must be a function
|
|
530
|
+
* @returns {(string|void)} tuple field name or `undefined`
|
|
531
|
+
*/
|
|
532
|
+
function findField( predicate, thisArg ) {
|
|
533
|
+
var bool;
|
|
534
|
+
var f;
|
|
535
|
+
var i;
|
|
536
|
+
if ( this !== tuple ) { // eslint-disable-line no-invalid-this
|
|
537
|
+
throw new TypeError( 'invalid invocation. `this` is not host tuple.' );
|
|
538
|
+
}
|
|
539
|
+
if ( !isFunction( predicate ) ) {
|
|
540
|
+
throw new TypeError( format( 'invalid argument. First argument must be a function. Value: `%s`.', predicate ) );
|
|
541
|
+
}
|
|
542
|
+
for ( i = 0; i < nfields; i++ ) {
|
|
543
|
+
f = fields[ indices[ i ] ];
|
|
544
|
+
bool = predicate.call( thisArg, tuple[ i ], i, f, tuple );
|
|
545
|
+
if ( bool ) {
|
|
546
|
+
return f;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* Returns the index of the first tuple element for which a provided predicate function returns a truthy value.
|
|
553
|
+
*
|
|
554
|
+
* ## Notes
|
|
555
|
+
*
|
|
556
|
+
* - If the predicate function never returns a truthy value, the function returns `-1`.
|
|
557
|
+
*
|
|
558
|
+
* @private
|
|
559
|
+
* @memberof tuple
|
|
560
|
+
* @param {Function} predicate - predicate function
|
|
561
|
+
* @param {*} [thisArg] - execution context
|
|
562
|
+
* @throws {TypeError} `this` must be the host tuple
|
|
563
|
+
* @throws {TypeError} first argument must be a function
|
|
564
|
+
* @returns {integer} tuple index or `-1`
|
|
565
|
+
*/
|
|
566
|
+
function findIndex( predicate, thisArg ) {
|
|
567
|
+
var bool;
|
|
568
|
+
var i;
|
|
569
|
+
if ( this !== tuple ) { // eslint-disable-line no-invalid-this
|
|
570
|
+
throw new TypeError( 'invalid invocation. `this` is not host tuple.' );
|
|
571
|
+
}
|
|
572
|
+
if ( !isFunction( predicate ) ) {
|
|
573
|
+
throw new TypeError( format( 'invalid argument. First argument must be a function. Value: `%s`.', predicate ) );
|
|
574
|
+
}
|
|
575
|
+
for ( i = 0; i < nfields; i++ ) {
|
|
576
|
+
bool = predicate.call( thisArg, tuple[ i ], i, fields[ indices[i] ], tuple );
|
|
577
|
+
if ( bool ) {
|
|
578
|
+
return i;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
return -1;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
/**
|
|
585
|
+
* Invokes a callback for each tuple element.
|
|
586
|
+
*
|
|
587
|
+
* @private
|
|
588
|
+
* @memberof tuple
|
|
589
|
+
* @param {Function} fcn - function to invoke
|
|
590
|
+
* @param {*} [thisArg] - execution context
|
|
591
|
+
* @throws {TypeError} `this` must be the host tuple
|
|
592
|
+
* @throws {TypeError} first argument must be a function
|
|
593
|
+
*/
|
|
594
|
+
function forEach( fcn, thisArg ) {
|
|
595
|
+
var i;
|
|
596
|
+
if ( this !== tuple ) { // eslint-disable-line no-invalid-this
|
|
597
|
+
throw new TypeError( 'invalid invocation. `this` is not host tuple.' );
|
|
598
|
+
}
|
|
599
|
+
if ( !isFunction( fcn ) ) {
|
|
600
|
+
throw new TypeError( format( 'invalid argument. First argument must be a function. Value: `%s`.', fcn ) );
|
|
601
|
+
}
|
|
602
|
+
for ( i = 0; i < nfields; i++ ) {
|
|
603
|
+
fcn.call( thisArg, tuple[ i ], i, fields[ indices[i] ], tuple );
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
/**
|
|
608
|
+
* Converts a tuple index to a field name.
|
|
609
|
+
*
|
|
610
|
+
* ## Notes
|
|
611
|
+
*
|
|
612
|
+
* - If provided an out-of-bounds index, the function returns `undefined`.
|
|
613
|
+
* - If provided a negative tuple index, the function resolves the index relative to the last tuple element.
|
|
614
|
+
*
|
|
615
|
+
* @private
|
|
616
|
+
* @memberof tuple
|
|
617
|
+
* @param {integer} ind - tuple index
|
|
618
|
+
* @throws {TypeError} `this` must be the host tuple
|
|
619
|
+
* @throws {TypeError} must provide an integer
|
|
620
|
+
* @returns {(string|void)} field name or undefined
|
|
621
|
+
*/
|
|
622
|
+
function ind2key( ind ) {
|
|
623
|
+
if ( this !== tuple ) { // eslint-disable-line no-invalid-this
|
|
624
|
+
throw new TypeError( 'invalid invocation. `this` is not host tuple.' );
|
|
625
|
+
}
|
|
626
|
+
if ( !isInteger( ind ) ) {
|
|
627
|
+
throw new TypeError( format( 'invalid argument. Must provide an integer. Value: `%s`.', ind ) );
|
|
628
|
+
}
|
|
629
|
+
if ( ind < 0 ) {
|
|
630
|
+
ind = nfields + ind;
|
|
631
|
+
}
|
|
632
|
+
if ( ind < 0 || ind >= nfields ) {
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
635
|
+
return fields[ indices[ ind ] ];
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
/**
|
|
639
|
+
* Converts a field name to a tuple index.
|
|
640
|
+
*
|
|
641
|
+
* ## Notes
|
|
642
|
+
*
|
|
643
|
+
* - If provided an unknown field name, the function returns `-1`.
|
|
644
|
+
*
|
|
645
|
+
* @private
|
|
646
|
+
* @memberof tuple
|
|
647
|
+
* @param {string} key - field name
|
|
648
|
+
* @throws {TypeError} `this` must be the host tuple
|
|
649
|
+
* @throws {TypeError} first argument must be a string
|
|
650
|
+
* @returns {integer} tuple index
|
|
651
|
+
*/
|
|
652
|
+
function key2ind( key ) {
|
|
653
|
+
var i;
|
|
654
|
+
if ( this !== tuple ) { // eslint-disable-line no-invalid-this
|
|
655
|
+
throw new TypeError( 'invalid invocation. `this` is not host tuple.' );
|
|
656
|
+
}
|
|
657
|
+
if ( !isString( key ) ) {
|
|
658
|
+
throw new TypeError( format( 'invalid argument. First argument must be a string. Value: `%s`.', key ) );
|
|
659
|
+
}
|
|
660
|
+
for ( i = 0; i < nfields; i++ ) {
|
|
661
|
+
if ( fields[ indices[i] ] === key ) {
|
|
662
|
+
return i;
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
return -1;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
/**
|
|
669
|
+
* Returns an iterator for iterating over tuple keys.
|
|
670
|
+
*
|
|
671
|
+
* @private
|
|
672
|
+
* @memberof tuple
|
|
673
|
+
* @throws {TypeError} `this` must be the host tuple
|
|
674
|
+
* @returns {Iterator} iterator
|
|
675
|
+
*/
|
|
676
|
+
function keys() {
|
|
677
|
+
var self;
|
|
678
|
+
var iter;
|
|
679
|
+
var FLG;
|
|
680
|
+
var i;
|
|
681
|
+
|
|
682
|
+
self = this; // eslint-disable-line no-invalid-this
|
|
683
|
+
if ( self !== tuple ) {
|
|
684
|
+
throw new TypeError( 'invalid invocation. `this` is not host tuple.' );
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
// Initialize the iteration index:
|
|
688
|
+
i = -1;
|
|
689
|
+
|
|
690
|
+
// Create an iterator protocol-compliant object:
|
|
691
|
+
iter = {};
|
|
692
|
+
defineProperty( iter, 'next', {
|
|
693
|
+
'configurable': false,
|
|
694
|
+
'enumerable': false,
|
|
695
|
+
'writable': false,
|
|
696
|
+
'value': next
|
|
697
|
+
});
|
|
698
|
+
defineProperty( iter, 'return', {
|
|
699
|
+
'configurable': false,
|
|
700
|
+
'enumerable': false,
|
|
701
|
+
'writable': false,
|
|
702
|
+
'value': end
|
|
703
|
+
});
|
|
704
|
+
if ( HAS_ITERATOR_SYMBOL ) {
|
|
705
|
+
defineProperty( iter, ITERATOR_SYMBOL, {
|
|
706
|
+
'configurable': false,
|
|
707
|
+
'enumerable': false,
|
|
708
|
+
'writable': false,
|
|
709
|
+
'value': factory
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
return iter;
|
|
713
|
+
|
|
714
|
+
/**
|
|
715
|
+
* Returns an iterator protocol-compliant object containing the next iterated value.
|
|
716
|
+
*
|
|
717
|
+
* @private
|
|
718
|
+
* @returns {Object} iterator protocol-compliant object
|
|
719
|
+
*/
|
|
720
|
+
function next() {
|
|
721
|
+
i += 1;
|
|
722
|
+
if ( FLG || i >= nfields ) {
|
|
723
|
+
return {
|
|
724
|
+
'done': true
|
|
725
|
+
};
|
|
726
|
+
}
|
|
727
|
+
return {
|
|
728
|
+
'value': [ i, fields[ indices[ i ] ] ],
|
|
729
|
+
'done': false
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* Finishes an iterator.
|
|
735
|
+
*
|
|
736
|
+
* @private
|
|
737
|
+
* @param {*} [value] - value to return
|
|
738
|
+
* @returns {Object} iterator protocol-compliant object
|
|
739
|
+
*/
|
|
740
|
+
function end( value ) {
|
|
741
|
+
FLG = true;
|
|
742
|
+
if ( arguments.length ) {
|
|
743
|
+
return {
|
|
744
|
+
'value': value,
|
|
745
|
+
'done': true
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
return {
|
|
749
|
+
'done': true
|
|
750
|
+
};
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
/**
|
|
754
|
+
* Returns a new iterator.
|
|
755
|
+
*
|
|
756
|
+
* @private
|
|
757
|
+
* @returns {Iterator} iterator
|
|
758
|
+
*/
|
|
759
|
+
function factory() {
|
|
760
|
+
return self.keys();
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
/**
|
|
765
|
+
* Returns the field of the last tuple element strictly equal to a search element, iterating from right to left.
|
|
766
|
+
*
|
|
767
|
+
* ## Notes
|
|
768
|
+
*
|
|
769
|
+
* - The function does not distinguish between signed and unsigned zero.
|
|
770
|
+
* - If unable to locate a search element, the function returns `undefined`.
|
|
771
|
+
*
|
|
772
|
+
* @private
|
|
773
|
+
* @memberof tuple
|
|
774
|
+
* @param {*} searchElement - search element
|
|
775
|
+
* @param {integer} [fromIndex=-1] - tuple index from which to begin searching
|
|
776
|
+
* @throws {TypeError} `this` must be the host tuple
|
|
777
|
+
* @throws {TypeError} second argument must be an integer
|
|
778
|
+
* @returns {(string|void)} tuple field name or `undefined`
|
|
779
|
+
*/
|
|
780
|
+
function lastFieldOf( searchElement ) {
|
|
781
|
+
var i;
|
|
782
|
+
if ( this !== tuple ) { // eslint-disable-line no-invalid-this
|
|
783
|
+
throw new TypeError( 'invalid invocation. `this` is not host tuple.' );
|
|
784
|
+
}
|
|
785
|
+
if ( arguments.length > 1 ) {
|
|
786
|
+
i = arguments[ 1 ];
|
|
787
|
+
if ( !isInteger( i ) ) {
|
|
788
|
+
throw new TypeError( format( 'invalid argument. Second argument must be an integer. Value: `%s`.', i ) );
|
|
789
|
+
}
|
|
790
|
+
if ( i >= nfields ) {
|
|
791
|
+
i = nfields - 1;
|
|
792
|
+
} else if ( i < 0 ) {
|
|
793
|
+
i = nfields + i;
|
|
794
|
+
if ( i < 0 ) {
|
|
795
|
+
return;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
} else {
|
|
799
|
+
i = nfields - 1;
|
|
800
|
+
}
|
|
801
|
+
for ( ; i >= 0; i-- ) {
|
|
802
|
+
if ( tuple[ i ] === searchElement ) {
|
|
803
|
+
return fields[ indices[ i ] ];
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
/**
|
|
809
|
+
* Maps each tuple element to an element in a new tuple.
|
|
810
|
+
*
|
|
811
|
+
* ## Notes
|
|
812
|
+
*
|
|
813
|
+
* - The returned tuple has the same data type as the host tuple.
|
|
814
|
+
*
|
|
815
|
+
* @private
|
|
816
|
+
* @memberof tuple
|
|
817
|
+
* @param {Function} fcn - map function
|
|
818
|
+
* @param {*} [thisArg] - execution context
|
|
819
|
+
* @throws {TypeError} `this` must be the host tuple
|
|
820
|
+
* @throws {TypeError} first argument must be a function
|
|
821
|
+
* @returns {TypedArray} new tuple
|
|
822
|
+
*/
|
|
823
|
+
function map( fcn, thisArg ) {
|
|
824
|
+
var out;
|
|
825
|
+
var i;
|
|
826
|
+
if ( this !== tuple ) { // eslint-disable-line no-invalid-this
|
|
827
|
+
throw new TypeError( 'invalid invocation. `this` is not host tuple.' );
|
|
828
|
+
}
|
|
829
|
+
if ( !isFunction( fcn ) ) {
|
|
830
|
+
throw new TypeError( format( 'invalid argument. First argument must be a function. Value: `%s`.', fcn ) );
|
|
831
|
+
}
|
|
832
|
+
out = namedtypedtuple( dtype );
|
|
833
|
+
for ( i = 0; i < nfields; i++ ) {
|
|
834
|
+
out[ i ] = fcn.call( thisArg, tuple[ i ], i, fields[ indices[i] ], tuple );
|
|
835
|
+
}
|
|
836
|
+
return out;
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
/**
|
|
840
|
+
* Applies a function against an accumulator and each element in a tuple and returns the accumulated result.
|
|
841
|
+
*
|
|
842
|
+
* @private
|
|
843
|
+
* @memberof tuple
|
|
844
|
+
* @param {Function} fcn - reduction function
|
|
845
|
+
* @param {*} [initial] - initial value
|
|
846
|
+
* @throws {TypeError} `this` must be the host tuple
|
|
847
|
+
* @throws {TypeError} first argument must be a function
|
|
848
|
+
* @returns {*} accumulated result
|
|
849
|
+
*/
|
|
850
|
+
function reduce( fcn ) {
|
|
851
|
+
var acc;
|
|
852
|
+
var i;
|
|
853
|
+
if ( this !== tuple ) { // eslint-disable-line no-invalid-this
|
|
854
|
+
throw new TypeError( 'invalid invocation. `this` is not host tuple.' );
|
|
855
|
+
}
|
|
856
|
+
if ( !isFunction( fcn ) ) {
|
|
857
|
+
throw new TypeError( format( 'invalid argument. First argument must be a function. Value: `%s`.', fcn ) );
|
|
858
|
+
}
|
|
859
|
+
if ( arguments.length > 1 ) {
|
|
860
|
+
acc = arguments[ 1 ];
|
|
861
|
+
i = 0;
|
|
862
|
+
} else {
|
|
863
|
+
acc = tuple[ 0 ];
|
|
864
|
+
i = 1;
|
|
865
|
+
}
|
|
866
|
+
for ( ; i < nfields; i++ ) {
|
|
867
|
+
acc = fcn( acc, tuple[ i ], i, fields[ indices[i] ], tuple );
|
|
868
|
+
}
|
|
869
|
+
return acc;
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
/**
|
|
873
|
+
* Applies a function against an accumulator and each element in a tuple and returns the accumulated result, iterating from right to left.
|
|
874
|
+
*
|
|
875
|
+
* @private
|
|
876
|
+
* @memberof tuple
|
|
877
|
+
* @param {Function} fcn - reduction function
|
|
878
|
+
* @param {*} [initial] - initial value
|
|
879
|
+
* @throws {TypeError} `this` must be the host tuple
|
|
880
|
+
* @throws {TypeError} first argument must be a function
|
|
881
|
+
* @returns {*} accumulated result
|
|
882
|
+
*/
|
|
883
|
+
function reduceRight( fcn ) {
|
|
884
|
+
var acc;
|
|
885
|
+
var i;
|
|
886
|
+
if ( this !== tuple ) { // eslint-disable-line no-invalid-this
|
|
887
|
+
throw new TypeError( 'invalid invocation. `this` is not host tuple.' );
|
|
888
|
+
}
|
|
889
|
+
if ( !isFunction( fcn ) ) {
|
|
890
|
+
throw new TypeError( format( 'invalid argument. First argument must be a function. Value: `%s`.', fcn ) );
|
|
891
|
+
}
|
|
892
|
+
if ( arguments.length > 1 ) {
|
|
893
|
+
acc = arguments[ 1 ];
|
|
894
|
+
i = nfields - 1;
|
|
895
|
+
} else {
|
|
896
|
+
acc = tuple[ nfields-1 ];
|
|
897
|
+
i = nfields - 2;
|
|
898
|
+
}
|
|
899
|
+
for ( ; i >= 0; i-- ) {
|
|
900
|
+
acc = fcn( acc, tuple[ i ], i, fields[ indices[i] ], tuple );
|
|
901
|
+
}
|
|
902
|
+
return acc;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
/**
|
|
906
|
+
* Reverses a tuple **in-place**.
|
|
907
|
+
*
|
|
908
|
+
* @private
|
|
909
|
+
* @memberof tuple
|
|
910
|
+
* @throws {TypeError} `this` must be the host tuple
|
|
911
|
+
* @returns {TypedArray} reversed tuple
|
|
912
|
+
*/
|
|
913
|
+
function reverse() {
|
|
914
|
+
var tmp;
|
|
915
|
+
var i;
|
|
916
|
+
var j;
|
|
917
|
+
if ( this !== tuple ) { // eslint-disable-line no-invalid-this
|
|
918
|
+
throw new TypeError( 'invalid invocation. `this` is not host tuple.' );
|
|
919
|
+
}
|
|
920
|
+
for ( i = 0; i < floor( nfields/2 ); i++ ) {
|
|
921
|
+
j = nfields - i - 1;
|
|
922
|
+
tmp = tuple[ i ];
|
|
923
|
+
tuple[ i ] = tuple[ j ];
|
|
924
|
+
tuple[ j ] = tmp;
|
|
925
|
+
}
|
|
926
|
+
// Because the indices are bounded [0,nfields), we can use simple arithmetic to "reverse" index values in-place...
|
|
927
|
+
for ( i = 0; i < nfields; i++ ) {
|
|
928
|
+
indices[ i ] = nfields - indices[ i ] - 1;
|
|
929
|
+
}
|
|
930
|
+
return tuple;
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
/**
|
|
934
|
+
* Copies elements to a new tuple with the same underlying data type as the host tuple.
|
|
935
|
+
*
|
|
936
|
+
* @private
|
|
937
|
+
* @memberof tuple
|
|
938
|
+
* @param {integer} [begin=0] - start element index (inclusive)
|
|
939
|
+
* @param {integer} [end=tuple.length] - end element index (exclusive)
|
|
940
|
+
* @throws {TypeError} `this` must be the host tuple
|
|
941
|
+
* @throws {TypeError} first argument must be an integer
|
|
942
|
+
* @throws {TypeError} second argument must be an integer
|
|
943
|
+
* @returns {TypedArray} new tuple
|
|
944
|
+
*/
|
|
945
|
+
function slice( begin, end ) {
|
|
946
|
+
var tmp;
|
|
947
|
+
var f;
|
|
948
|
+
var i;
|
|
949
|
+
var j;
|
|
950
|
+
|
|
951
|
+
if ( this !== tuple ) { // eslint-disable-line no-invalid-this
|
|
952
|
+
throw new TypeError( 'invalid invocation. `this` is not host tuple.' );
|
|
953
|
+
}
|
|
954
|
+
if ( arguments.length === 0 ) {
|
|
955
|
+
return namedtypedtuple( tuple, dtype );
|
|
956
|
+
}
|
|
957
|
+
i = begin;
|
|
958
|
+
if ( !isInteger( i ) ) {
|
|
959
|
+
throw new TypeError( format( 'invalid argument. First argument must be an integer. Value: `%s`.', begin ) );
|
|
960
|
+
}
|
|
961
|
+
if ( i < 0 ) {
|
|
962
|
+
i = nfields + i;
|
|
963
|
+
if ( i < 0 ) {
|
|
964
|
+
i = 0;
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
if ( arguments.length === 1 ) {
|
|
968
|
+
j = nfields;
|
|
969
|
+
} else {
|
|
970
|
+
j = end;
|
|
971
|
+
if ( !isInteger( j ) ) {
|
|
972
|
+
throw new TypeError( format( 'invalid argument. Second argument must be an integer. Value: `%s`.', end ) );
|
|
973
|
+
}
|
|
974
|
+
if ( j < 0 ) {
|
|
975
|
+
j = nfields + j;
|
|
976
|
+
if ( j < 0 ) {
|
|
977
|
+
j = 0;
|
|
978
|
+
}
|
|
979
|
+
} else if ( j > nfields ) {
|
|
980
|
+
j = nfields;
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
f = [];
|
|
984
|
+
tmp = [];
|
|
985
|
+
for ( ; i < j; i++ ) {
|
|
986
|
+
f.push( fields[ indices[i] ] );
|
|
987
|
+
tmp.push( tuple[ i ] );
|
|
988
|
+
}
|
|
989
|
+
return factory( f, opts )( tmp, dtype );
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
/**
|
|
993
|
+
* Tests whether at least one tuple element passes a test implemented by a predicate function.
|
|
994
|
+
*
|
|
995
|
+
* @private
|
|
996
|
+
* @memberof tuple
|
|
997
|
+
* @param {Function} predicate - predicate function
|
|
998
|
+
* @param {*} [thisArg] - execution context
|
|
999
|
+
* @throws {TypeError} `this` must be the host tuple
|
|
1000
|
+
* @throws {TypeError} first argument must be a function
|
|
1001
|
+
* @returns {boolean} boolean indicating if at least one element passes
|
|
1002
|
+
*/
|
|
1003
|
+
function some( predicate, thisArg ) {
|
|
1004
|
+
var bool;
|
|
1005
|
+
var i;
|
|
1006
|
+
if ( this !== tuple ) { // eslint-disable-line no-invalid-this
|
|
1007
|
+
throw new TypeError( 'invalid invocation. `this` is not host tuple.' );
|
|
1008
|
+
}
|
|
1009
|
+
if ( !isFunction( predicate ) ) {
|
|
1010
|
+
throw new TypeError( format( 'invalid argument. First argument must be a function. Value: `%s`.', predicate ) );
|
|
1011
|
+
}
|
|
1012
|
+
for ( i = 0; i < nfields; i++ ) {
|
|
1013
|
+
bool = predicate.call( thisArg, tuple[ i ], i, fields[ indices[i] ], tuple );
|
|
1014
|
+
if ( bool ) {
|
|
1015
|
+
return true;
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
return false;
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
/**
|
|
1022
|
+
* Sorts a tuple in-place.
|
|
1023
|
+
*
|
|
1024
|
+
* ## Notes
|
|
1025
|
+
*
|
|
1026
|
+
* - The comparison function is provided two tuple elements, `a` and `b`, per invocation, and its return value determines the sort order as follows:
|
|
1027
|
+
*
|
|
1028
|
+
* - If the comparison function returns a value **less** than zero, then the function sorts `a` to an index lower than `b` (i.e., `a` should come **before** `b`).
|
|
1029
|
+
* - If the comparison function returns a value **greater** than zero, then the function sorts `a` to an index higher than `b` (i.e., `b` should come **before** `a`).
|
|
1030
|
+
* - If the comparison function returns **zero**, then the relative order of `a` and `b` _should_ remain unchanged.
|
|
1031
|
+
*
|
|
1032
|
+
* - Invoking this method does **not** affect tuple field assignments.
|
|
1033
|
+
*
|
|
1034
|
+
* @private
|
|
1035
|
+
* @memberof tuple
|
|
1036
|
+
* @param {Function} [compareFunction] - function which specifies the sort order
|
|
1037
|
+
* @throws {TypeError} `this` must be the host tuple
|
|
1038
|
+
* @throws {TypeError} first argument must be a function
|
|
1039
|
+
* @returns {TypedArray} sorted tuple
|
|
1040
|
+
*/
|
|
1041
|
+
function sort( compareFunction ) {
|
|
1042
|
+
var clbk;
|
|
1043
|
+
var tmp;
|
|
1044
|
+
var i;
|
|
1045
|
+
var j;
|
|
1046
|
+
var k;
|
|
1047
|
+
var v;
|
|
1048
|
+
if ( this !== tuple ) { // eslint-disable-line no-invalid-this
|
|
1049
|
+
throw new TypeError( 'invalid invocation. `this` is not host tuple.' );
|
|
1050
|
+
}
|
|
1051
|
+
if ( arguments.length ) {
|
|
1052
|
+
if ( !isFunction( compareFunction ) ) {
|
|
1053
|
+
throw new TypeError( format( 'invalid argument. First argument must be a function. Value: `%s`.', compareFunction ) );
|
|
1054
|
+
}
|
|
1055
|
+
clbk = compareFunction;
|
|
1056
|
+
} else {
|
|
1057
|
+
clbk = ascending;
|
|
1058
|
+
}
|
|
1059
|
+
indices.sort( wrapper );
|
|
1060
|
+
|
|
1061
|
+
// Create a temporary indices array which we'll reorder as we rearrange the tuple elements:
|
|
1062
|
+
tmp = indices.slice();
|
|
1063
|
+
|
|
1064
|
+
// Rearrange tuple elements according to the rearranged indices (note: every "move" moves a tuple element to its desired position with runtime complexity O(N))...
|
|
1065
|
+
for ( i = 0; i < nfields; i++ ) {
|
|
1066
|
+
// Check if we need to move a tuple element:
|
|
1067
|
+
if ( tmp[ i ] !== i ) {
|
|
1068
|
+
v = tuple[ i ];
|
|
1069
|
+
j = i;
|
|
1070
|
+
k = tmp[ j ];
|
|
1071
|
+
|
|
1072
|
+
// Follow "cycles", stopping once we are back at index `i`...
|
|
1073
|
+
while ( k !== i ) {
|
|
1074
|
+
tuple[ j ] = tuple[ k ];
|
|
1075
|
+
tmp[ j ] = j;
|
|
1076
|
+
j = k;
|
|
1077
|
+
k = tmp[ j ];
|
|
1078
|
+
}
|
|
1079
|
+
tuple[ j ] = v;
|
|
1080
|
+
tmp[ j ] = j;
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
return tuple;
|
|
1084
|
+
|
|
1085
|
+
/**
|
|
1086
|
+
* Wraps a comparison function to allow sorting the internal indices array rather than the tuple directly.
|
|
1087
|
+
*
|
|
1088
|
+
* @private
|
|
1089
|
+
* @param {NonNegativeInteger} ia - first index
|
|
1090
|
+
* @param {NonNegativeInteger} ib - second index
|
|
1091
|
+
* @returns {*} value specifying the sort order
|
|
1092
|
+
*/
|
|
1093
|
+
function wrapper( ia, ib ) {
|
|
1094
|
+
var a = tuple[ indices[ ia ] ];
|
|
1095
|
+
var b = tuple[ indices[ ib ] ];
|
|
1096
|
+
return clbk( a, b );
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
/**
|
|
1101
|
+
* Creates a new tuple over the same underlying `ArrayBuffer` and with the same underlying data type as the host tuple.
|
|
1102
|
+
*
|
|
1103
|
+
* @private
|
|
1104
|
+
* @memberof tuple
|
|
1105
|
+
* @param {integer} [begin=0] - start element index (inclusive)
|
|
1106
|
+
* @param {integer} [end=tuple.length] - end element index (exclusive)
|
|
1107
|
+
* @throws {TypeError} `this` must be the host tuple
|
|
1108
|
+
* @throws {TypeError} first argument must be an integer
|
|
1109
|
+
* @throws {TypeError} second argument must be an integer
|
|
1110
|
+
* @returns {TypedArray} new tuple
|
|
1111
|
+
*/
|
|
1112
|
+
function subtuple( begin, end ) {
|
|
1113
|
+
var f;
|
|
1114
|
+
var i;
|
|
1115
|
+
var j;
|
|
1116
|
+
var k;
|
|
1117
|
+
|
|
1118
|
+
if ( this !== tuple ) { // eslint-disable-line no-invalid-this
|
|
1119
|
+
throw new TypeError( 'invalid invocation. `this` is not host tuple.' );
|
|
1120
|
+
}
|
|
1121
|
+
if ( arguments.length === 0 ) {
|
|
1122
|
+
return namedtypedtuple( tuple.buffer, tuple.byteOffset, dtype );
|
|
1123
|
+
}
|
|
1124
|
+
i = begin;
|
|
1125
|
+
if ( !isInteger( i ) ) {
|
|
1126
|
+
throw new TypeError( format( 'invalid argument. First argument must be an integer. Value: `%s`.', begin ) );
|
|
1127
|
+
}
|
|
1128
|
+
if ( i < 0 ) {
|
|
1129
|
+
i = nfields + i;
|
|
1130
|
+
if ( i < 0 ) {
|
|
1131
|
+
i = 0;
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
if ( arguments.length === 1 ) {
|
|
1135
|
+
j = nfields;
|
|
1136
|
+
} else {
|
|
1137
|
+
j = end;
|
|
1138
|
+
if ( !isInteger( j ) ) {
|
|
1139
|
+
throw new TypeError( format( 'invalid argument. Second argument must be an integer. Value: `%s`.', end ) );
|
|
1140
|
+
}
|
|
1141
|
+
if ( j < 0 ) {
|
|
1142
|
+
j = nfields + j;
|
|
1143
|
+
if ( j < 0 ) {
|
|
1144
|
+
j = 0;
|
|
1145
|
+
}
|
|
1146
|
+
} else if ( j > nfields ) {
|
|
1147
|
+
j = nfields;
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
if ( j <= i ) {
|
|
1151
|
+
return factory( [], opts )( tuple.buffer, tuple.byteOffset, dtype );
|
|
1152
|
+
}
|
|
1153
|
+
f = [];
|
|
1154
|
+
for ( k = i; k < j; k++ ) {
|
|
1155
|
+
f.push( fields[ indices[k] ] );
|
|
1156
|
+
}
|
|
1157
|
+
return factory( f, opts )( tuple.buffer, tuple.byteOffset+(i*tuple.BYTES_PER_ELEMENT), dtype );
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
/**
|
|
1161
|
+
* Serializes a tuple as JSON.
|
|
1162
|
+
*
|
|
1163
|
+
* @private
|
|
1164
|
+
* @memberof tuple
|
|
1165
|
+
* @throws {TypeError} `this` must be the host tuple
|
|
1166
|
+
* @returns {JSON} tuple JSON representation
|
|
1167
|
+
*/
|
|
1168
|
+
function toJSON() {
|
|
1169
|
+
var out;
|
|
1170
|
+
var i;
|
|
1171
|
+
if ( this !== tuple ) { // eslint-disable-line no-invalid-this
|
|
1172
|
+
throw new TypeError( 'invalid invocation. `this` is not host tuple.' );
|
|
1173
|
+
}
|
|
1174
|
+
out = {};
|
|
1175
|
+
for ( i = 0; i < nfields; i++ ) {
|
|
1176
|
+
out[ fields[i] ] = tuple[ indices[i] ];
|
|
1177
|
+
}
|
|
1178
|
+
return out;
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
/**
|
|
1182
|
+
* Serializes a tuple as a locale-specific string.
|
|
1183
|
+
*
|
|
1184
|
+
* @private
|
|
1185
|
+
* @memberof tuple
|
|
1186
|
+
* @param {(string|Array<string>)} [locales] - locale identifier(s)
|
|
1187
|
+
* @param {Object} [options] - configuration options
|
|
1188
|
+
* @throws {TypeError} `this` must be the host tuple
|
|
1189
|
+
* @throws {TypeError} first argument must be a string or an array of strings
|
|
1190
|
+
* @throws {TypeError} options argument must be an object
|
|
1191
|
+
* @returns {string} string representation
|
|
1192
|
+
*/
|
|
1193
|
+
function toLocaleString( locales, options ) {
|
|
1194
|
+
var loc;
|
|
1195
|
+
var out;
|
|
1196
|
+
var o;
|
|
1197
|
+
var i;
|
|
1198
|
+
|
|
1199
|
+
if ( this !== tuple ) { // eslint-disable-line no-invalid-this
|
|
1200
|
+
throw new TypeError( 'invalid invocation. `this` is not host tuple.' );
|
|
1201
|
+
}
|
|
1202
|
+
if ( arguments.length === 0 ) {
|
|
1203
|
+
loc = [];
|
|
1204
|
+
} else if ( isString( locales ) || isStringArray( locales ) ) {
|
|
1205
|
+
loc = locales;
|
|
1206
|
+
} else {
|
|
1207
|
+
throw new TypeError( format( 'invalid argument. First argument must be a string or an array of strings. Value: `%s`.', locales ) );
|
|
1208
|
+
}
|
|
1209
|
+
if ( arguments.length < 2 ) {
|
|
1210
|
+
o = {};
|
|
1211
|
+
} else if ( isObject( options ) ) {
|
|
1212
|
+
o = options;
|
|
1213
|
+
} else {
|
|
1214
|
+
throw new TypeError( format( 'invalid argument. Options argument must be an object. Value: `%s`.', options ) );
|
|
1215
|
+
}
|
|
1216
|
+
out = opts.name.toLocaleString( loc, o ) + '(';
|
|
1217
|
+
for ( i = 0; i < nfields; i++ ) {
|
|
1218
|
+
out += fields[ i ].toLocaleString( loc, o );
|
|
1219
|
+
out += '=';
|
|
1220
|
+
out += tuple[ indices[ i ] ].toLocaleString( loc, o );
|
|
1221
|
+
if ( i < nfields-1 ) {
|
|
1222
|
+
out += ', ';
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
out += ')';
|
|
1226
|
+
return out;
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1229
|
+
/**
|
|
1230
|
+
* Serializes a tuple as a string.
|
|
1231
|
+
*
|
|
1232
|
+
* @private
|
|
1233
|
+
* @memberof tuple
|
|
1234
|
+
* @throws {TypeError} `this` must be the host tuple
|
|
1235
|
+
* @returns {string} tuple string representation
|
|
1236
|
+
*/
|
|
1237
|
+
function toString() {
|
|
1238
|
+
var out;
|
|
1239
|
+
var i;
|
|
1240
|
+
if ( this !== tuple ) { // eslint-disable-line no-invalid-this
|
|
1241
|
+
throw new TypeError( 'invalid invocation. `this` is not host tuple.' );
|
|
1242
|
+
}
|
|
1243
|
+
out = opts.name + '(';
|
|
1244
|
+
for ( i = 0; i < nfields; i++ ) {
|
|
1245
|
+
out += fields[ i ];
|
|
1246
|
+
out += '=';
|
|
1247
|
+
out += tuple[ indices[ i ] ];
|
|
1248
|
+
if ( i < nfields-1 ) {
|
|
1249
|
+
out += ', ';
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
out += ')';
|
|
1253
|
+
return out;
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
/**
|
|
1258
|
+
* Returns the list of tuple fields.
|
|
1259
|
+
*
|
|
1260
|
+
* @private
|
|
1261
|
+
* @memberof tuple
|
|
1262
|
+
* @returns {StringArray} tuple fields
|
|
1263
|
+
*/
|
|
1264
|
+
function getFields() {
|
|
1265
|
+
return fields.slice();
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
// Note: keep the following methods in alphabetical order...
|
|
1269
|
+
|
|
1270
|
+
/**
|
|
1271
|
+
* Creates a new tuple from an array-like object or an iterable.
|
|
1272
|
+
*
|
|
1273
|
+
* @private
|
|
1274
|
+
* @name from
|
|
1275
|
+
* @memberof namedtypedtuple
|
|
1276
|
+
* @type {Function}
|
|
1277
|
+
* @param {(ArrayLikeObject|Iterable)} src - array-like object or iterable
|
|
1278
|
+
* @param {Function} [clbk] - callback to invoke for each source element
|
|
1279
|
+
* @param {*} [thisArg] - callback execution context
|
|
1280
|
+
* @throws {TypeError} `this` must be the host tuple factory
|
|
1281
|
+
* @throws {TypeError} first argument must be an array-like object or an iterable
|
|
1282
|
+
* @throws {RangeError} source must be compatible with tuple length
|
|
1283
|
+
* @throws {TypeError} second argument must be a function
|
|
1284
|
+
* @returns {TypedArray} new tuple
|
|
1285
|
+
*/
|
|
1286
|
+
defineProperty( namedtypedtuple, 'from', {
|
|
1287
|
+
'configurable': false,
|
|
1288
|
+
'enumerable': false,
|
|
1289
|
+
'writable': false,
|
|
1290
|
+
'value': function from( src ) { // eslint-disable-line no-restricted-syntax
|
|
1291
|
+
var thisArg;
|
|
1292
|
+
var nargs;
|
|
1293
|
+
var tuple;
|
|
1294
|
+
var clbk;
|
|
1295
|
+
var tmp;
|
|
1296
|
+
var it;
|
|
1297
|
+
var i;
|
|
1298
|
+
if ( this !== namedtypedtuple ) {
|
|
1299
|
+
throw new TypeError( 'invalid invocation. `this` is not the host tuple factory.' );
|
|
1300
|
+
}
|
|
1301
|
+
nargs = arguments.length;
|
|
1302
|
+
if ( nargs > 1 ) {
|
|
1303
|
+
clbk = arguments[ 1 ];
|
|
1304
|
+
if ( !isFunction( clbk ) ) {
|
|
1305
|
+
throw new TypeError( format( 'invalid argument. Second argument must be a function. Value: `%s`.', clbk ) );
|
|
1306
|
+
}
|
|
1307
|
+
if ( nargs > 2 ) {
|
|
1308
|
+
thisArg = arguments[ 2 ];
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
if ( isCollection( src ) ) {
|
|
1312
|
+
if ( src.length !== nfields ) {
|
|
1313
|
+
throw new RangeError( format( 'invalid argument. Source is incompatible with the number of tuple fields. Number of fields: `%u`. Source length: `%u`.', nfields, src.length ) );
|
|
1314
|
+
}
|
|
1315
|
+
tuple = namedtypedtuple( nfields, opts.dtype );
|
|
1316
|
+
if ( clbk ) {
|
|
1317
|
+
for ( i = 0; i < nfields; i++ ) {
|
|
1318
|
+
tuple[ i ] = clbk.call( thisArg, src[ i ], i, fields[ i ] );
|
|
1319
|
+
}
|
|
1320
|
+
} else {
|
|
1321
|
+
for ( i = 0; i < nfields; i++ ) {
|
|
1322
|
+
tuple[ i ] = src[ i ];
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
} else if ( isObject( src ) && HAS_ITERATOR_SYMBOL && isFunction( src[ ITERATOR_SYMBOL ] ) ) {
|
|
1326
|
+
it = src[ ITERATOR_SYMBOL ]();
|
|
1327
|
+
if ( !isFunction( it.next ) ) {
|
|
1328
|
+
throw new TypeError( format( 'invalid argument. First argument must be an array-like object or an iterable. Value: `%s`.', src ) );
|
|
1329
|
+
}
|
|
1330
|
+
if ( clbk ) {
|
|
1331
|
+
tmp = fromIteratorMap( fields, it, clbk, thisArg );
|
|
1332
|
+
} else {
|
|
1333
|
+
tmp = fromIterator( it );
|
|
1334
|
+
}
|
|
1335
|
+
tuple = namedtypedtuple( tmp, opts.dtype );
|
|
1336
|
+
} else {
|
|
1337
|
+
throw new TypeError( format( 'invalid argument. First argument must be an array-like object or an iterable. Value: `%s`.', src ) );
|
|
1338
|
+
}
|
|
1339
|
+
return tuple;
|
|
1340
|
+
}
|
|
1341
|
+
});
|
|
1342
|
+
|
|
1343
|
+
/**
|
|
1344
|
+
* Creates a new tuple from an object containing tuple fields.
|
|
1345
|
+
*
|
|
1346
|
+
* @private
|
|
1347
|
+
* @name fromObject
|
|
1348
|
+
* @memberof namedtypedtuple
|
|
1349
|
+
* @type {Function}
|
|
1350
|
+
* @param {Object} obj - source object
|
|
1351
|
+
* @param {Function} [clbk] - callback to invoke for each source object tuple field
|
|
1352
|
+
* @param {*} [thisArg] - callback execution context
|
|
1353
|
+
* @throws {TypeError} `this` must be the host tuple factory
|
|
1354
|
+
* @throws {TypeError} first argument must be an object
|
|
1355
|
+
* @throws {TypeError} second argument must be a function
|
|
1356
|
+
* @returns {TypedArray} new tuple
|
|
1357
|
+
*/
|
|
1358
|
+
defineProperty( namedtypedtuple, 'fromObject', {
|
|
1359
|
+
'configurable': false,
|
|
1360
|
+
'enumerable': false,
|
|
1361
|
+
'writable': false,
|
|
1362
|
+
'value': function fromObject( obj ) { // eslint-disable-line no-restricted-syntax
|
|
1363
|
+
var thisArg;
|
|
1364
|
+
var nargs;
|
|
1365
|
+
var tuple;
|
|
1366
|
+
var clbk;
|
|
1367
|
+
var f;
|
|
1368
|
+
var i;
|
|
1369
|
+
if ( this !== namedtypedtuple ) {
|
|
1370
|
+
throw new TypeError( 'invalid invocation. `this` is not the host tuple factory.' );
|
|
1371
|
+
}
|
|
1372
|
+
if ( obj === null || typeof obj !== 'object' ) {
|
|
1373
|
+
throw new TypeError( format( 'invalid argument. First argument must be an object. Value: `%s`.', obj ) );
|
|
1374
|
+
}
|
|
1375
|
+
nargs = arguments.length;
|
|
1376
|
+
if ( nargs > 1 ) {
|
|
1377
|
+
clbk = arguments[ 1 ];
|
|
1378
|
+
if ( !isFunction( clbk ) ) {
|
|
1379
|
+
throw new TypeError( format( 'invalid argument. Second argument must be a function. Value: `%s`.', clbk ) );
|
|
1380
|
+
}
|
|
1381
|
+
if ( nargs > 2 ) {
|
|
1382
|
+
thisArg = arguments[ 2 ];
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
tuple = namedtypedtuple( nfields, opts.dtype );
|
|
1386
|
+
if ( clbk ) {
|
|
1387
|
+
for ( i = 0; i < nfields; i++ ) {
|
|
1388
|
+
f = fields[ i ];
|
|
1389
|
+
if ( hasOwnProp( obj, f ) ) {
|
|
1390
|
+
tuple[ i ] = clbk.call( thisArg, obj[ f ], f );
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
} else {
|
|
1394
|
+
for ( i = 0; i < nfields; i++ ) {
|
|
1395
|
+
f = fields[ i ];
|
|
1396
|
+
if ( hasOwnProp( obj, f ) ) {
|
|
1397
|
+
tuple[ i ] = obj[ f ];
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
return tuple;
|
|
1402
|
+
}
|
|
1403
|
+
});
|
|
1404
|
+
|
|
1405
|
+
/**
|
|
1406
|
+
* Creates a new tuple from a variable number of arguments.
|
|
1407
|
+
*
|
|
1408
|
+
* @private
|
|
1409
|
+
* @name of
|
|
1410
|
+
* @memberof namedtypedtuple
|
|
1411
|
+
* @type {Function}
|
|
1412
|
+
* @param {...number} element - tuple elements
|
|
1413
|
+
* @throws {TypeError} `this` must be the host tuple factory
|
|
1414
|
+
* @throws {RangeError} incompatible number of arguments
|
|
1415
|
+
* @returns {TypedArray} new tuple
|
|
1416
|
+
*/
|
|
1417
|
+
defineProperty( namedtypedtuple, 'of', {
|
|
1418
|
+
'configurable': false,
|
|
1419
|
+
'enumerable': false,
|
|
1420
|
+
'writable': false,
|
|
1421
|
+
'value': function of() { // eslint-disable-line no-restricted-syntax
|
|
1422
|
+
var args;
|
|
1423
|
+
var i;
|
|
1424
|
+
if ( this !== namedtypedtuple ) {
|
|
1425
|
+
throw new TypeError( 'invalid invocation. `this` is not the host tuple factory.' );
|
|
1426
|
+
}
|
|
1427
|
+
if ( arguments.length !== nfields ) {
|
|
1428
|
+
throw new RangeError( format( 'invalid invocation. Number of arguments is incompatible with the number of tuple fields. Number of fields: `%u`. Number of arguments: `%u`.', nfields, arguments.length ) );
|
|
1429
|
+
}
|
|
1430
|
+
args = [];
|
|
1431
|
+
for ( i = 0; i < arguments.length; i++ ) {
|
|
1432
|
+
args.push( arguments[ i ] );
|
|
1433
|
+
}
|
|
1434
|
+
return namedtypedtuple( args );
|
|
1435
|
+
}
|
|
1436
|
+
});
|
|
1437
|
+
|
|
1438
|
+
return namedtypedtuple;
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
|
|
1442
|
+
// EXPORTS //
|
|
1443
|
+
|
|
1444
|
+
module.exports = factory;
|