Skip to content

Commit 32e6b7b

Browse files
committed
feat(patterns): For containerHasSplit(copyArray, ...), scan from the start
Ref #3065 (comment)
1 parent 7c4e5e1 commit 32e6b7b

2 files changed

Lines changed: 17 additions & 16 deletions

File tree

packages/patterns/src/patterns/patternMatchers.js

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1326,27 +1326,26 @@ const makePatternKit = () => {
13261326
* @param {Pattern} elementPatt
13271327
* @param {bigint} bound Must be >= 1n
13281328
* @param {Rejector} reject
1329-
* @param {T[]} [inResults]
1330-
* @param {T[]} [outResults]
1329+
* @param {T[] | undefined} inResults
1330+
* @param {T[] | undefined} outResults
1331+
* @param {-1 | 1} direction -1 for picking from the end (which gives
1332+
* intuitive results with descending lexicographic CopySet payloads); 1 for
1333+
* picking from the start (which gives intuitive results with other arrays)
13311334
* @returns {boolean}
13321335
*/
13331336
const confirmElementsHasSplit = (
13341337
elements,
13351338
elementPatt,
13361339
bound,
13371340
reject,
1338-
inResults = undefined,
1339-
outResults = undefined,
1341+
inResults,
1342+
outResults,
1343+
direction,
13401344
) => {
13411345
let inCount = 0n;
1342-
// Since this feature is motivated by ERTP's use on
1343-
// non-fungible (`set`, `copySet`) amounts,
1344-
// their arrays store their elements in decending lexicographic order.
1345-
// But this function has to make some choice amoung equally good minimal
1346-
// results. It is more intuitive for the choice to be the first `bound`
1347-
// matching elements in ascending lexicigraphic order, rather than
1348-
// decending. Thus we iterate `elements` in reverse order.
1349-
for (let i = elements.length - 1; i >= 0; i -= 1) {
1346+
const firstIndex = direction === -1 ? elements.length - 1 : 0;
1347+
const stopIndex = direction === -1 ? -1 : elements.length;
1348+
for (let i = firstIndex; i !== stopIndex; i += direction) {
13501349
const element = elements[i];
13511350
if (inCount >= bound) {
13521351
if (!outResults) break;
@@ -1446,6 +1445,7 @@ const makePatternKit = () => {
14461445
reject,
14471446
inResults,
14481447
outResults,
1448+
1,
14491449
) && [harden(inResults), harden(outResults)]
14501450
);
14511451
}
@@ -1458,6 +1458,7 @@ const makePatternKit = () => {
14581458
reject,
14591459
inResults,
14601460
outResults,
1461+
-1,
14611462
) && [
14621463
inResults && makeCopySet(inResults),
14631464
outResults && makeCopySet(outResults),

packages/patterns/test/containerHasSplit.test.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,16 @@ const testContainerHasSplit = test.macro((t, config) => {
8282
specimen,
8383
pattern: M.string(),
8484
bound: 1n,
85-
expectAccepted: ['bar'],
86-
expectRejected: [2, 'foo', 1],
85+
expectAccepted: ['foo'],
86+
expectRejected: [1, 2, 'bar'],
8787
});
8888

8989
test('split first two matches from copyArray', testContainerHasSplit, {
9090
specimen,
9191
pattern: M.string(),
9292
bound: 2n,
93-
expectAccepted: ['bar', 'foo'],
94-
expectRejected: [2, 1],
93+
expectAccepted: ['foo', 'bar'],
94+
expectRejected: [1, 2],
9595
});
9696

9797
test('fail against copyArray', testContainerHasSplit, {

0 commit comments

Comments
 (0)