Skip to content

Add flex.coll.subtract/containsAll/containsAny/flatten helpers#45

Open
shahar-biron wants to merge 4 commits intomainfrom
feature/coll-helpers-contains-flatten
Open

Add flex.coll.subtract/containsAll/containsAny/flatten helpers#45
shahar-biron wants to merge 4 commits intomainfrom
feature/coll-helpers-contains-flatten

Conversation

@shahar-biron
Copy link
Collaborator

@shahar-biron shahar-biron commented Dec 25, 2025

This PR implements the remaining collection helpers proposed in scope-features/read-only-flex-scope.md section 2.3 (Rich Collection Helpers).\n\n### Changes\n- Add new collection helper modules under src/collections/:\n - flex.coll.subtract(list, toRemove) – remove elements appearing in toRemove from list, preserving order.\n - flex.coll.containsAll(list, candidates) – true iff all non-null candidates are contained in the list.\n - flex.coll.containsAny(list, candidates) – true iff any non-null candidate is contained in the list.\n - flex.coll.flatten(nestedList) – one-level flatten of nested lists.\n- Register UDFs as coll.subtract, coll.containsAll, coll.containsAny, and coll.flatten.\n- Export the helper functions via module.exports for Jest, matching the existing pattern used by frequencies, union, zip, etc.\n- Add tests/collections/subtractContainsFlatten.test.js which exercises each helper both via FLEX UDFs in FalkorDB and via direct module imports.\n\n### Notes\n- All tests pass locally with:\n - FLEX_USE_LOCAL_FALKORDB=1 npm test -- --coverage --coverageReporters=json-summary\n- Collections coverage is now near 100% for the new helpers.\n\nRelated issue: #44

Summary by CodeRabbit

  • New Features
    • Added collection utilities: containsAll, containsAny, flatten (one-level), and subtract — null-tolerant, strict-equality checks, preserved element order.
  • Improvements
    • Enhanced union behavior for mixed/non-array inputs: deterministic order, deduplication, and allocation-efficient handling.
  • Tests
    • Added integration tests covering typical, null/empty edge cases and both API/module-level behavior for the new utilities.

✏️ Tip: You can customize this high-level summary in your review settings.

PR Summary by Typo

Overview

This PR introduces four new utility functions for collection manipulation (subtract, containsAll, containsAny, flatten) and refactors the existing union function for improved performance and robustness. These additions enhance the flex.coll library with more versatile array operations.

Key Changes

  • Added flex.coll.subtract to return a new list with specified elements removed.
  • Added flex.coll.containsAll to check if a list contains all elements from a candidate list.
  • Added flex.coll.containsAny to check if a list contains any element from a candidate list.
  • Added flex.coll.flatten for one-level flattening of nested arrays.
  • Refactored flex.coll.union to be more allocation- and GC-friendly, and to handle non-array inputs more gracefully.
  • Included new integration tests for all added collection helpers.

Work Breakdown

Category Lines Changed
New Work 302 (98.4%)
Rework 5 (1.6%)
Total Changes 307
To turn off PR summary, please visit Notification settings.

@typo-app
Copy link

typo-app bot commented Dec 25, 2025

Static Code Review 📊

✅ All quality checks passed!

@coderabbitai
Copy link

coderabbitai bot commented Dec 25, 2025

📝 Walkthrough

Walkthrough

Adds four collection utility modules—containsAll, containsAny, flatten, subtract—each registered with falkor and conditionally CommonJS-exported, updates union implementation to preserve order and handle non-array inputs efficiently, and adds an integration test exercising these helpers and their NULL/empty-edge behaviors.

Changes

Cohort / File(s) Summary
New Collection Utilities
src/collections/containsAll.js, src/collections/containsAny.js, src/collections/flatten.js, src/collections/subtract.js
Added implementations for: containsAll(list, candidates) (subset check; ignores null/undefined candidates; validates arrays), containsAny(list, candidates) (any-match; same null/array handling), flatten(nested) (one-level flatten; returns [] for non-array), and subtract(list, toRemove) (difference preserving order). Each is registered via falkor.register('coll.*', ...) and conditionally exported with module.exports when available.
Union Implementation Update
src/collections/union.js
Replaced simple Set-based dedup with order-preserving, allocation-efficient logic: explicit non-array handling, early returns for single-array or empty inputs, seed result from a and append only unique items from b using Set tracking; JSDoc updated to reflect `Array
Integration Test
tests/collections/subtractContainsFlatten.test.js
New test file validating the four helpers via FLEX queries and direct module calls; covers typical cases, empty inputs, and NULL/undefined handling.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I hopped through lists and sets with care,
Ignored the nulls, found who was there,
Flattened the layers, swept out the line,
Subtracted the crumbs — order kept fine. 🥕


📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Free

📥 Commits

Reviewing files that changed from the base of the PR and between 8f777a7 and 66c1221.

📒 Files selected for processing (1)
  • src/collections/union.js

Note

🎁 Summarized by CodeRabbit Free

Your organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login.

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Dec 25, 2025

Coverage report

Caution

Test run failed

St.
Category Percentage Covered / Total
🔴 Statements
46.72% (-41.74% 🔻)
249/533
🔴 Branches
44.59% (-28.35% 🔻)
140/314
🟡 Functions
74.19% (-25.81% 🔻)
46/62
🔴 Lines
50.79% (-42.19% 🔻)
225/443
Show new covered files 🐣
St.
File Statements Branches Functions Lines
🔴
... / levenshtein.js
2.94% 0% 0% 4%
🔴
... / jaroWinkler.js
1.75% 0% 0% 2.44%
🟢
... / subtract.js
100% 100% 100% 100%
🟢
... / containsAll.js
91.67% 90% 100% 100%
🟢
... / containsAny.js
91.67% 90% 100% 100%
🟢
... / flatten.js
100% 100% 100% 100%
Show files with reduced coverage 🔻
St.
File Statements Branches Functions Lines
🟢
... / union.js
80.77% (-19.23% 🔻)
63.64% (-36.36% 🔻)
100% 100%
🔴 date/format.js
0% (-66% 🔻)
0% (-26.92% 🔻)
0% (-100% 🔻)
0% (-68.89% 🔻)
🔴 date/parse.js
0% (-90.24% 🔻)
0% (-72.73% 🔻)
0% (-100% 🔻)
0% (-94.59% 🔻)
🔴 date/toTimeZone.js
0% (-75.86% 🔻)
0% (-58.33% 🔻)
0% (-100% 🔻)
0% (-80% 🔻)
🔴 date/truncate.js
0% (-82.93% 🔻)
0% (-59.09% 🔻)
0% (-100% 🔻)
0% (-87.18% 🔻)
🔴
... / jaccard.js
0% (-100% 🔻)
0% (-100% 🔻)
0% (-100% 🔻)
0% (-100% 🔻)

Test suite run failed

Failed tests: 7/70. Failed suites: 3/27.
  ● FLEX Levenshtein Integration Tests › flex.sim.levenshtein basic string distance





  ● FLEX Levenshtein Integration Tests › flex.sim.levenshtein handles nulls gracefully





  ● FLEX Levenshtein Integration Tests › flex.sim.levenshtein symmetry






  ● FLEX Jaro-Winkler Integration Tests › flex.sim.jaroWinkler basic similarity





  ● FLEX Jaro-Winkler Integration Tests › flex.sim.jaroWinkler handles nulls





  ● FLEX Jaro-Winkler Integration Tests › flex.sim.jaroWinkler symmetry






  ● FLEX Jaccard Integration Tests › flex.sim.jaccard

    expect(received).toBe(expected) // Object.is equality

    Expected: 1
    Received: null

      53 |
      54 |         expect(result.data[0]['name']).toBe('Alice');
    > 55 |         expect(result.data[0]['sim']).toBe(1);
         |                                       ^
      56 |
      57 |         expect(result.data[1]['name']).toBe('Bob');
      58 |         expect(result.data[1]['sim']).toBe(0.2);

      at Object.toBe (tests/similarity/jaccard.test.js:55:39)

Report generated by 🧪jest coverage report action from 66c1221

Copy link

@typo-app typo-app bot left a comment

Choose a reason for hiding this comment

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

AI Code Review 🤖

Files Reviewed: 6
Comments Added: 2
Lines of Code Analyzed: 312
Critical Issues: 0

PR Health: Excellent 🔥

Give 👍 or 👎 on each review comment to help us improve.

handling toRemove null

Co-authored-by: typo-app[bot] <139475626+typo-app[bot]@users.noreply.github.com>
Co-Authored-By: Warp <agent@warp.dev>
Copy link
Contributor

@swilly22 swilly22 left a comment

Choose a reason for hiding this comment

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

Do you see these functions in APOC?
each function should have its own test file
each function should be documented under the docs folder.

Co-Authored-By: Warp <agent@warp.dev>
// Seed the Set with `a` and copy `a` to result.
// This preserves the relative order of elements in `a`.
const set = new Set(a);
const result = a.slice();
Copy link

Choose a reason for hiding this comment

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

logic: The union function keeps duplicates from the first array a. Initialize result from the set to ensure uniqueness.

Suggested change
const result = a.slice();
const result = [...set];

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants