From 793d059061d78baf58ed5d42499fe3bda01140aa Mon Sep 17 00:00:00 2001 From: jmoenig Date: Thu, 4 Feb 2021 18:59:27 +0100 Subject: [PATCH] changed query semantics for table selectors in ITEM OF to rows, columns, planes, etc. --- HISTORY.md | 6 ++++++ snap.html | 4 ++-- src/lists.js | 53 ++++++++++++++++++++++++++++++++++++++------------ src/threads.js | 10 ++-------- 4 files changed, 51 insertions(+), 22 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 43003f18..f2d77139 100755 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,12 @@ ## in development: +* **Notable Changes:** + * 2D lists inside ITEM OF now have the right order of dimensions (rows, columns, planes, etc.) + +### 2021-02-04 +* lists, threads: changed query semantics for table selectors in ITEM OF to rows, columns, planes, etc. + ### 2021-02-03 * new dev version diff --git a/snap.html b/snap.html index cb1a6ca9..097484a6 100755 --- a/snap.html +++ b/snap.html @@ -9,11 +9,11 @@ - + - + diff --git a/src/lists.js b/src/lists.js index 85bf83ad..947c17b7 100644 --- a/src/lists.js +++ b/src/lists.js @@ -63,7 +63,7 @@ MorphicPreferences, TableDialogMorph, SpriteBubbleMorph, SpeechBubbleMorph, TableFrameMorph, TableMorph, Variable, isSnapObject, Costume, contains, detect, ZERO, WHITE*/ -modules.lists = '2021-February-02'; +modules.lists = '2021-February-04'; var List; var ListWatcherMorph; @@ -394,7 +394,34 @@ List.prototype.version = function (startRow, rows, startCol, cols) { // List matrix operations and utilities - very experimental +List.prototype.query = function (indices) { + // assumes a 2D argument list where each slot represents + // the indices to select from a dimension + // e.g. [rows, columns, planes] + var select; + if (indices.isEmpty()) { + return this.map(e => e); + } + if (indices.quickRank() === 1) { + return indices.map(i => this.at(i)); + } + select = indices.at(1).isEmpty() ? + this.range(1, this.length()) + : indices.at(1); + return select.map(i => this.at(i)).map( + e => e instanceof List? e.query(indices.cdr()) : e + ); +}; + +List.prototype.range = function (start, end) { + // private - answer a list of ascending numbers, incremented by 1 + return new List([...Array(end - start + 1)].map((e, i) => i + start)); +}; + List.prototype.items = function (indices) { + // deprecated. Same as query() above, except in reverse order. + // e.g. [planes, columns, rows] + // This. This is it. The pinnacle of my programmer's life. // After days of roaming about my house and garden, // of taking showers and rummaging through the fridge, @@ -458,24 +485,26 @@ List.prototype.ravel = function () { return new List(all); }; -List.prototype.rank = function (quick) { +List.prototype.rank = function () { // answer the number of my dimensions - if (quick) { // only look at the first elements of each dimension - var rank = 0, - cur = this; - while (cur instanceof List) { - rank += 1; - cur = cur.at(1); - } - return rank; - } - // traverse the whole structure for irregularly shaped nested lists return 1 + Math.max(...this.itemsArray().map(item => item instanceof List ? item.rank() : 0) ); }; +List.prototype.quickRank = function (quick) { + // answer the number of my dimensions + // only look at the first elements of each dimension + var rank = 0, + cur = this; + while (cur instanceof List) { + rank += 1; + cur = cur.at(1); + } + return rank; +}; + List.prototype.shape = function () { // answer a list of the maximum size for each dimension var dim, diff --git a/src/threads.js b/src/threads.js index b0d244bb..4bd01a10 100644 --- a/src/threads.js +++ b/src/threads.js @@ -61,7 +61,7 @@ StageMorph, SpriteMorph, StagePrompterMorph, Note, modules, isString, copy, Map, isNil, WatcherMorph, List, ListWatcherMorph, alert, console, TableMorph, BLACK, TableFrameMorph, ColorSlotMorph, isSnapObject, newCanvas, Symbol, SVG_Costume*/ -modules.threads = '2021-February-02'; +modules.threads = '2021-February-04'; var ThreadManager; var Process; @@ -1943,13 +1943,7 @@ Process.prototype.reportListItem = function (index, list) { return list.at(list.length()); } if (index instanceof List && this.enableHyperOps) { - if (index.rank(true) === 1) { // quick - only look at first element - if (index.isEmpty()) { - return list.map(item => item); - } - return index.map(idx => list.at(idx)); - } - return list.items(index); + return list.query(index); } return list.at(index); };