Skip to content

$each / $merge iterate arrays like JS for..in - #131

Merged
aeberhart merged 2 commits into
mainfrom
each-merge-arrays
Nov 5, 2026
Merged

aeberhart merged 2 commits into
mainfrom
each-merge-arrays

Conversation

@aeberhart

Copy link
Copy Markdown
Contributor

First of three PRs split out of #130 (partial function application, #95). This one has no dependencies and should be merged first.

What changed

  • Functions.each(Object obj, Object func) (was Map obj): when obj is a List, it goes through the elements and passes the index as a string key ("0", "1", …), like JS for (var key in obj). Maps work as before.
  • Functions.merge: array entries are merged as {"0": …, "1": …}. Entries that are neither a list nor a map are skipped instead of throwing a ClassCastException.

Why

In jsonata-js, for..in also goes through arrays. Signature validation (<o-f?:a>, <a<o>:o>) normally keeps arrays out of these functions, but some calls skip the signature check, e.g. partial application in jsonata-js ([5,6] ~> $each(?, …), #79). Without this change, the upcoming partial-application PR would turn the current T0410 error into a ClassCastException.

Notes for reviewers

  • This PR does not change any JSONata expression that works today: calling $each([5,6], …) directly is still rejected with T0410, and a test checks this.
  • each's parameter type changed from Map to Object. This only matters to Java code that calls Functions.each directly.

Testing

New EachMergeTest (12 cases). The tests register custom functions without a signature ($eachRaw / $mergeRaw) so that arrays reach each / merge. Full suite: 1748 tests, 0 failures.

🤖 Generated with Claude Code

JS "for (var key in obj)" also iterates arrays, using the indexes as
string keys. Arrays only reach these functions where the signature is
not validated (e.g. partial application, see #79 / #95), where the Java
port threw a ClassCastException.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@aeberhart
aeberhart requested a review from uw4 November 4, 2026 15:11
@github-actions

github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

Test Results

1 825 tests  +19   1 823 ✅ +19   9s ⏱️ -1s
  124 suites + 2       2 💤 ± 0 
  124 files   + 2       0 ❌ ± 0 

Results for commit d680e54. ± Comparison against base commit 4814c81.

♻️ This comment has been updated with latest results.

// Java: JS "for (var key in obj)" also iterates arrays (keys are the indexes as strings).
// Can happen where the signature is not validated, e.g. $each(?, ...)
var list = (List)obj;
for (int i=0; i<list.size(); i++) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a one-time cast, unlike the code above.

@uw4 uw4 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Addresses review comments on #131.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@aeberhart
aeberhart merged commit 6bb65b9 into main Nov 5, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants