ArrayNode.js (5653B)
1 import { isArrayNode, isNode } from '../../utils/is.js'; 2 import { map } from '../../utils/array.js'; 3 import { factory } from '../../utils/factory.js'; 4 var name = 'ArrayNode'; 5 var dependencies = ['Node']; 6 export var createArrayNode = /* #__PURE__ */factory(name, dependencies, _ref => { 7 var { 8 Node 9 } = _ref; 10 11 /** 12 * @constructor ArrayNode 13 * @extends {Node} 14 * Holds an 1-dimensional array with items 15 * @param {Node[]} [items] 1 dimensional array with items 16 */ 17 function ArrayNode(items) { 18 if (!(this instanceof ArrayNode)) { 19 throw new SyntaxError('Constructor must be called with the new operator'); 20 } 21 22 this.items = items || []; // validate input 23 24 if (!Array.isArray(this.items) || !this.items.every(isNode)) { 25 throw new TypeError('Array containing Nodes expected'); 26 } 27 } 28 29 ArrayNode.prototype = new Node(); 30 ArrayNode.prototype.type = 'ArrayNode'; 31 ArrayNode.prototype.isArrayNode = true; 32 /** 33 * Compile a node into a JavaScript function. 34 * This basically pre-calculates as much as possible and only leaves open 35 * calculations which depend on a dynamic scope with variables. 36 * @param {Object} math Math.js namespace with functions and constants. 37 * @param {Object} argNames An object with argument names as key and `true` 38 * as value. Used in the SymbolNode to optimize 39 * for arguments from user assigned functions 40 * (see FunctionAssignmentNode) or special symbols 41 * like `end` (see IndexNode). 42 * @return {function} Returns a function which can be called like: 43 * evalNode(scope: Object, args: Object, context: *) 44 */ 45 46 ArrayNode.prototype._compile = function (math, argNames) { 47 var evalItems = map(this.items, function (item) { 48 return item._compile(math, argNames); 49 }); 50 var asMatrix = math.config.matrix !== 'Array'; 51 52 if (asMatrix) { 53 var matrix = math.matrix; 54 return function evalArrayNode(scope, args, context) { 55 return matrix(map(evalItems, function (evalItem) { 56 return evalItem(scope, args, context); 57 })); 58 }; 59 } else { 60 return function evalArrayNode(scope, args, context) { 61 return map(evalItems, function (evalItem) { 62 return evalItem(scope, args, context); 63 }); 64 }; 65 } 66 }; 67 /** 68 * Execute a callback for each of the child nodes of this node 69 * @param {function(child: Node, path: string, parent: Node)} callback 70 */ 71 72 73 ArrayNode.prototype.forEach = function (callback) { 74 for (var i = 0; i < this.items.length; i++) { 75 var node = this.items[i]; 76 callback(node, 'items[' + i + ']', this); 77 } 78 }; 79 /** 80 * Create a new ArrayNode having it's childs be the results of calling 81 * the provided callback function for each of the childs of the original node. 82 * @param {function(child: Node, path: string, parent: Node): Node} callback 83 * @returns {ArrayNode} Returns a transformed copy of the node 84 */ 85 86 87 ArrayNode.prototype.map = function (callback) { 88 var items = []; 89 90 for (var i = 0; i < this.items.length; i++) { 91 items[i] = this._ifNode(callback(this.items[i], 'items[' + i + ']', this)); 92 } 93 94 return new ArrayNode(items); 95 }; 96 /** 97 * Create a clone of this node, a shallow copy 98 * @return {ArrayNode} 99 */ 100 101 102 ArrayNode.prototype.clone = function () { 103 return new ArrayNode(this.items.slice(0)); 104 }; 105 /** 106 * Get string representation 107 * @param {Object} options 108 * @return {string} str 109 * @override 110 */ 111 112 113 ArrayNode.prototype._toString = function (options) { 114 var items = this.items.map(function (node) { 115 return node.toString(options); 116 }); 117 return '[' + items.join(', ') + ']'; 118 }; 119 /** 120 * Get a JSON representation of the node 121 * @returns {Object} 122 */ 123 124 125 ArrayNode.prototype.toJSON = function () { 126 return { 127 mathjs: 'ArrayNode', 128 items: this.items 129 }; 130 }; 131 /** 132 * Instantiate an ArrayNode from its JSON representation 133 * @param {Object} json An object structured like 134 * `{"mathjs": "ArrayNode", items: [...]}`, 135 * where mathjs is optional 136 * @returns {ArrayNode} 137 */ 138 139 140 ArrayNode.fromJSON = function (json) { 141 return new ArrayNode(json.items); 142 }; 143 /** 144 * Get HTML representation 145 * @param {Object} options 146 * @return {string} str 147 * @override 148 */ 149 150 151 ArrayNode.prototype.toHTML = function (options) { 152 var items = this.items.map(function (node) { 153 return node.toHTML(options); 154 }); 155 return '<span class="math-parenthesis math-square-parenthesis">[</span>' + items.join('<span class="math-separator">,</span>') + '<span class="math-parenthesis math-square-parenthesis">]</span>'; 156 }; 157 /** 158 * Get LaTeX representation 159 * @param {Object} options 160 * @return {string} str 161 */ 162 163 164 ArrayNode.prototype._toTex = function (options) { 165 function itemsToTex(items, nested) { 166 var mixedItems = items.some(isArrayNode) && !items.every(isArrayNode); 167 var itemsFormRow = nested || mixedItems; 168 var itemSep = itemsFormRow ? '&' : '\\\\'; 169 var itemsTex = items.map(function (node) { 170 if (node.items) { 171 return itemsToTex(node.items, !nested); 172 } else { 173 return node.toTex(options); 174 } 175 }).join(itemSep); 176 return mixedItems || !itemsFormRow || itemsFormRow && !nested ? '\\begin{bmatrix}' + itemsTex + '\\end{bmatrix}' : itemsTex; 177 } 178 179 return itemsToTex(this.items, false); 180 }; 181 182 return ArrayNode; 183 }, { 184 isClass: true, 185 isNode: true 186 });