collection.js (5221B)
1 "use strict"; 2 3 Object.defineProperty(exports, "__esModule", { 4 value: true 5 }); 6 exports.containsCollections = containsCollections; 7 exports.deepForEach = deepForEach; 8 exports.deepMap = deepMap; 9 exports.reduce = reduce; 10 exports.scatter = scatter; 11 12 var _is = require("./is.js"); 13 14 var _IndexError = require("../error/IndexError.js"); 15 16 var _array = require("./array.js"); 17 18 var _switch2 = require("./switch.js"); 19 20 /** 21 * Test whether an array contains collections 22 * @param {Array} array 23 * @returns {boolean} Returns true when the array contains one or multiple 24 * collections (Arrays or Matrices). Returns false otherwise. 25 */ 26 function containsCollections(array) { 27 for (var i = 0; i < array.length; i++) { 28 if ((0, _is.isCollection)(array[i])) { 29 return true; 30 } 31 } 32 33 return false; 34 } 35 /** 36 * Recursively loop over all elements in a given multi dimensional array 37 * and invoke the callback on each of the elements. 38 * @param {Array | Matrix} array 39 * @param {Function} callback The callback method is invoked with one 40 * parameter: the current element in the array 41 */ 42 43 44 function deepForEach(array, callback) { 45 if ((0, _is.isMatrix)(array)) { 46 array = array.valueOf(); 47 } 48 49 for (var i = 0, ii = array.length; i < ii; i++) { 50 var value = array[i]; 51 52 if (Array.isArray(value)) { 53 deepForEach(value, callback); 54 } else { 55 callback(value); 56 } 57 } 58 } 59 /** 60 * Execute the callback function element wise for each element in array and any 61 * nested array 62 * Returns an array with the results 63 * @param {Array | Matrix} array 64 * @param {Function} callback The callback is called with two parameters: 65 * value1 and value2, which contain the current 66 * element of both arrays. 67 * @param {boolean} [skipZeros] Invoke callback function for non-zero values only. 68 * 69 * @return {Array | Matrix} res 70 */ 71 72 73 function deepMap(array, callback, skipZeros) { 74 if (array && typeof array.map === 'function') { 75 // TODO: replace array.map with a for loop to improve performance 76 return array.map(function (x) { 77 return deepMap(x, callback, skipZeros); 78 }); 79 } else { 80 return callback(array); 81 } 82 } 83 /** 84 * Reduce a given matrix or array to a new matrix or 85 * array with one less dimension, applying the given 86 * callback in the selected dimension. 87 * @param {Array | Matrix} mat 88 * @param {number} dim 89 * @param {Function} callback 90 * @return {Array | Matrix} res 91 */ 92 93 94 function reduce(mat, dim, callback) { 95 var size = Array.isArray(mat) ? (0, _array.arraySize)(mat) : mat.size(); 96 97 if (dim < 0 || dim >= size.length) { 98 // TODO: would be more clear when throwing a DimensionError here 99 throw new _IndexError.IndexError(dim, size.length); 100 } 101 102 if ((0, _is.isMatrix)(mat)) { 103 return mat.create(_reduce(mat.valueOf(), dim, callback)); 104 } else { 105 return _reduce(mat, dim, callback); 106 } 107 } 108 /** 109 * Recursively reduce a matrix 110 * @param {Array} mat 111 * @param {number} dim 112 * @param {Function} callback 113 * @returns {Array} ret 114 * @private 115 */ 116 117 118 function _reduce(mat, dim, callback) { 119 var i, ret, val, tran; 120 121 if (dim <= 0) { 122 if (!Array.isArray(mat[0])) { 123 val = mat[0]; 124 125 for (i = 1; i < mat.length; i++) { 126 val = callback(val, mat[i]); 127 } 128 129 return val; 130 } else { 131 tran = (0, _switch2._switch)(mat); 132 ret = []; 133 134 for (i = 0; i < tran.length; i++) { 135 ret[i] = _reduce(tran[i], dim - 1, callback); 136 } 137 138 return ret; 139 } 140 } else { 141 ret = []; 142 143 for (i = 0; i < mat.length; i++) { 144 ret[i] = _reduce(mat[i], dim - 1, callback); 145 } 146 147 return ret; 148 } 149 } // TODO: document function scatter 150 151 152 function scatter(a, j, w, x, u, mark, cindex, f, inverse, update, value) { 153 // a arrays 154 var avalues = a._values; 155 var aindex = a._index; 156 var aptr = a._ptr; // vars 157 158 var k, k0, k1, i; // check we need to process values (pattern matrix) 159 160 if (x) { 161 // values in j 162 for (k0 = aptr[j], k1 = aptr[j + 1], k = k0; k < k1; k++) { 163 // row 164 i = aindex[k]; // check value exists in current j 165 166 if (w[i] !== mark) { 167 // i is new entry in j 168 w[i] = mark; // add i to pattern of C 169 170 cindex.push(i); // x(i) = A, check we need to call function this time 171 172 if (update) { 173 // copy value to workspace calling callback function 174 x[i] = inverse ? f(avalues[k], value) : f(value, avalues[k]); // function was called on current row 175 176 u[i] = mark; 177 } else { 178 // copy value to workspace 179 x[i] = avalues[k]; 180 } 181 } else { 182 // i exists in C already 183 x[i] = inverse ? f(avalues[k], x[i]) : f(x[i], avalues[k]); // function was called on current row 184 185 u[i] = mark; 186 } 187 } 188 } else { 189 // values in j 190 for (k0 = aptr[j], k1 = aptr[j + 1], k = k0; k < k1; k++) { 191 // row 192 i = aindex[k]; // check value exists in current j 193 194 if (w[i] !== mark) { 195 // i is new entry in j 196 w[i] = mark; // add i to pattern of C 197 198 cindex.push(i); 199 } else { 200 // indicate function was called on current row 201 u[i] = mark; 202 } 203 } 204 } 205 }