UNPKG

8.18 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.createIndexClass = void 0;
7
8var _is = require("../../utils/is.js");
9
10var _object = require("../../utils/object.js");
11
12var _number = require("../../utils/number.js");
13
14var _factory = require("../../utils/factory.js");
15
16var name = 'Index';
17var dependencies = ['ImmutableDenseMatrix'];
18var createIndexClass = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
19 var ImmutableDenseMatrix = _ref.ImmutableDenseMatrix;
20
21 /**
22 * Create an index. An Index can store ranges and sets for multiple dimensions.
23 * Matrix.get, Matrix.set, and math.subset accept an Index as input.
24 *
25 * Usage:
26 * const index = new Index(range1, range2, matrix1, array1, ...)
27 *
28 * Where each parameter can be any of:
29 * A number
30 * A string (containing a name of an object property)
31 * An instance of Range
32 * An Array with the Set values
33 * A Matrix with the Set values
34 *
35 * The parameters start, end, and step must be integer numbers.
36 *
37 * @class Index
38 * @Constructor Index
39 * @param {...*} ranges
40 */
41 function Index(ranges) {
42 if (!(this instanceof Index)) {
43 throw new SyntaxError('Constructor must be called with the new operator');
44 }
45
46 this._dimensions = [];
47 this._isScalar = true;
48
49 for (var i = 0, ii = arguments.length; i < ii; i++) {
50 var arg = arguments[i];
51
52 if ((0, _is.isRange)(arg)) {
53 this._dimensions.push(arg);
54
55 this._isScalar = false;
56 } else if (Array.isArray(arg) || (0, _is.isMatrix)(arg)) {
57 // create matrix
58 var m = _createImmutableMatrix(arg.valueOf());
59
60 this._dimensions.push(m); // size
61
62
63 var size = m.size(); // scalar
64
65 if (size.length !== 1 || size[0] !== 1) {
66 this._isScalar = false;
67 }
68 } else if (typeof arg === 'number') {
69 this._dimensions.push(_createImmutableMatrix([arg]));
70 } else if (typeof arg === 'string') {
71 // object property (arguments.count should be 1)
72 this._dimensions.push(arg);
73 } else {
74 throw new TypeError('Dimension must be an Array, Matrix, number, string, or Range');
75 } // TODO: implement support for wildcard '*'
76
77 }
78 }
79 /**
80 * Attach type information
81 */
82
83
84 Index.prototype.type = 'Index';
85 Index.prototype.isIndex = true;
86
87 function _createImmutableMatrix(arg) {
88 // loop array elements
89 for (var i = 0, l = arg.length; i < l; i++) {
90 if (typeof arg[i] !== 'number' || !(0, _number.isInteger)(arg[i])) {
91 throw new TypeError('Index parameters must be positive integer numbers');
92 }
93 } // create matrix
94
95
96 return new ImmutableDenseMatrix(arg);
97 }
98 /**
99 * Create a clone of the index
100 * @memberof Index
101 * @return {Index} clone
102 */
103
104
105 Index.prototype.clone = function () {
106 var index = new Index();
107 index._dimensions = (0, _object.clone)(this._dimensions);
108 index._isScalar = this._isScalar;
109 return index;
110 };
111 /**
112 * Create an index from an array with ranges/numbers
113 * @memberof Index
114 * @param {Array.<Array | number>} ranges
115 * @return {Index} index
116 * @private
117 */
118
119
120 Index.create = function (ranges) {
121 var index = new Index();
122 Index.apply(index, ranges);
123 return index;
124 };
125 /**
126 * Retrieve the size of the index, the number of elements for each dimension.
127 * @memberof Index
128 * @returns {number[]} size
129 */
130
131
132 Index.prototype.size = function () {
133 var size = [];
134
135 for (var i = 0, ii = this._dimensions.length; i < ii; i++) {
136 var d = this._dimensions[i];
137 size[i] = typeof d === 'string' ? 1 : d.size()[0];
138 }
139
140 return size;
141 };
142 /**
143 * Get the maximum value for each of the indexes ranges.
144 * @memberof Index
145 * @returns {number[]} max
146 */
147
148
149 Index.prototype.max = function () {
150 var values = [];
151
152 for (var i = 0, ii = this._dimensions.length; i < ii; i++) {
153 var range = this._dimensions[i];
154 values[i] = typeof range === 'string' ? range : range.max();
155 }
156
157 return values;
158 };
159 /**
160 * Get the minimum value for each of the indexes ranges.
161 * @memberof Index
162 * @returns {number[]} min
163 */
164
165
166 Index.prototype.min = function () {
167 var values = [];
168
169 for (var i = 0, ii = this._dimensions.length; i < ii; i++) {
170 var range = this._dimensions[i];
171 values[i] = typeof range === 'string' ? range : range.min();
172 }
173
174 return values;
175 };
176 /**
177 * Loop over each of the ranges of the index
178 * @memberof Index
179 * @param {Function} callback Called for each range with a Range as first
180 * argument, the dimension as second, and the
181 * index object as third.
182 */
183
184
185 Index.prototype.forEach = function (callback) {
186 for (var i = 0, ii = this._dimensions.length; i < ii; i++) {
187 callback(this._dimensions[i], i, this);
188 }
189 };
190 /**
191 * Retrieve the dimension for the given index
192 * @memberof Index
193 * @param {Number} dim Number of the dimension
194 * @returns {Range | null} range
195 */
196
197
198 Index.prototype.dimension = function (dim) {
199 return this._dimensions[dim] || null;
200 };
201 /**
202 * Test whether this index contains an object property
203 * @returns {boolean} Returns true if the index is an object property
204 */
205
206
207 Index.prototype.isObjectProperty = function () {
208 return this._dimensions.length === 1 && typeof this._dimensions[0] === 'string';
209 };
210 /**
211 * Returns the object property name when the Index holds a single object property,
212 * else returns null
213 * @returns {string | null}
214 */
215
216
217 Index.prototype.getObjectProperty = function () {
218 return this.isObjectProperty() ? this._dimensions[0] : null;
219 };
220 /**
221 * Test whether this index contains only a single value.
222 *
223 * This is the case when the index is created with only scalar values as ranges,
224 * not for ranges resolving into a single value.
225 * @memberof Index
226 * @return {boolean} isScalar
227 */
228
229
230 Index.prototype.isScalar = function () {
231 return this._isScalar;
232 };
233 /**
234 * Expand the Index into an array.
235 * For example new Index([0,3], [2,7]) returns [[0,1,2], [2,3,4,5,6]]
236 * @memberof Index
237 * @returns {Array} array
238 */
239
240
241 Index.prototype.toArray = function () {
242 var array = [];
243
244 for (var i = 0, ii = this._dimensions.length; i < ii; i++) {
245 var dimension = this._dimensions[i];
246 array.push(typeof dimension === 'string' ? dimension : dimension.toArray());
247 }
248
249 return array;
250 };
251 /**
252 * Get the primitive value of the Index, a two dimensional array.
253 * Equivalent to Index.toArray().
254 * @memberof Index
255 * @returns {Array} array
256 */
257
258
259 Index.prototype.valueOf = Index.prototype.toArray;
260 /**
261 * Get the string representation of the index, for example '[2:6]' or '[0:2:10, 4:7, [1,2,3]]'
262 * @memberof Index
263 * @returns {String} str
264 */
265
266 Index.prototype.toString = function () {
267 var strings = [];
268
269 for (var i = 0, ii = this._dimensions.length; i < ii; i++) {
270 var dimension = this._dimensions[i];
271
272 if (typeof dimension === 'string') {
273 strings.push(JSON.stringify(dimension));
274 } else {
275 strings.push(dimension.toString());
276 }
277 }
278
279 return '[' + strings.join(', ') + ']';
280 };
281 /**
282 * Get a JSON representation of the Index
283 * @memberof Index
284 * @returns {Object} Returns a JSON object structured as:
285 * `{"mathjs": "Index", "ranges": [{"mathjs": "Range", start: 0, end: 10, step:1}, ...]}`
286 */
287
288
289 Index.prototype.toJSON = function () {
290 return {
291 mathjs: 'Index',
292 dimensions: this._dimensions
293 };
294 };
295 /**
296 * Instantiate an Index from a JSON object
297 * @memberof Index
298 * @param {Object} json A JSON object structured as:
299 * `{"mathjs": "Index", "dimensions": [{"mathjs": "Range", start: 0, end: 10, step:1}, ...]}`
300 * @return {Index}
301 */
302
303
304 Index.fromJSON = function (json) {
305 return Index.create(json.dimensions);
306 };
307
308 return Index;
309}, {
310 isClass: true
311});
312exports.createIndexClass = createIndexClass;
\No newline at end of file