-
-
Notifications
You must be signed in to change notification settings - Fork 28
Implement withLatestFrom for multiple flows (3-10 flows) with optimized Array-based implementation #370
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Co-authored-by: hoc081098 <36917223+hoc081098@users.noreply.github.com>
…ive tests Co-authored-by: hoc081098 <36917223+hoc081098@users.noreply.github.com>
@copilot I see the code pattern is duplicate? |
…y-based function Co-authored-by: hoc081098 <36917223+hoc081098@users.noreply.github.com>
I've refactored the code to eliminate duplication as requested. Created a new public function that accepts Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements support for combining multiple flows (3-10 flows) with the withLatestFrom
operator, providing both typed overloads for type safety and an efficient Array-based implementation to eliminate code duplication.
- Added 8 new overloads supporting 3-10 flows with typed parameters and transform functions
- Introduced a new Array-based core function that all multi-flow overloads delegate to, reducing code duplication by 48%
- Comprehensive test coverage for all new overloads including edge cases, error handling, and null value support
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
File | Description |
---|---|
src/commonMain/kotlin/com/hoc081098/flowext/withLatestFrom.kt | Core implementation with Array-based function and 8 typed overloads (3-10 flows) |
src/commonTest/kotlin/com/hoc081098/flowext/WithLatestFromTest.kt | Comprehensive test suite covering all new overloads with various scenarios |
src/commonMain/kotlin/com/hoc081098/flowext/withLatestFrom.kt.backup | Backup file showing previous implementation approach |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
val values = Array<Any?>(refs.size) { index -> | ||
refs[index].value ?: return@collect | ||
} | ||
|
||
val unboxedValues = Array<Any?>(values.size) { index -> | ||
INTERNAL_NULL_VALUE.unbox(values[index]) | ||
} | ||
|
Copilot
AI
Sep 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code creates an intermediate values
array and then immediately creates another unboxedValues
array. This could be optimized by combining both operations into a single array creation to reduce memory allocations.
val values = Array<Any?>(refs.size) { index -> | |
refs[index].value ?: return@collect | |
} | |
val unboxedValues = Array<Any?>(values.size) { index -> | |
INTERNAL_NULL_VALUE.unbox(values[index]) | |
} | |
val unboxedValues = Array<Any?>(refs.size) { index -> | |
val v = refs[index].value ?: return@collect | |
INTERNAL_NULL_VALUE.unbox(v) | |
} | |
Copilot uses AI. Check for mistakes.
transform( | ||
value, | ||
others[0] as B, | ||
others[1] as C, |
Copilot
AI
Sep 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The unchecked cast as B
and as C
could fail at runtime if the array contains values of different types than expected. Consider adding runtime type checks or documenting this assumption clearly.
transform( | |
value, | |
others[0] as B, | |
others[1] as C, | |
val b = others[0] | |
val c = others[1] | |
if (b !is B) { | |
throw IllegalStateException("Expected others[0] to be of type B, but was ${b?.let { it::class }}") | |
} | |
if (c !is C) { | |
throw IllegalStateException("Expected others[1] to be of type C, but was ${c?.let { it::class }}") | |
} | |
transform( | |
value, | |
b, | |
c, |
Copilot uses AI. Check for mistakes.
This PR extends the
withLatestFrom
operator to support combining multiple flows (3-10 flows), addressing the issue request for "withLatestFrom for many flows".Changes Made
Core Implementation
withLatestFrom
insrc/commonMain/kotlin/com/hoc081098/flowext/withLatestFrom.kt
supporting 3-10 flowsTriple<A, B, C>
for 3 flowscoroutineScope
and job cancellationArray-Based Core Function
withLatestFrom(others: Array<out Flow<*>>, transform: suspend (A, Array<Any?>) -> R)
that serves as the foundation for all multi-flow overloadsArray<AtomicRef<Any?>>
for efficient thread-safe latest value storageAPI Examples
Test Coverage
src/commonTest/kotlin/com/hoc081098/flowext/WithLatestFromTest.kt
Implementation Details
INTERNAL_NULL_VALUE
pattern for null handling as existing codelaunch(start = CoroutineStart.UNDISPATCHED)
combine.kt
The implementation maintains the core semantics of
withLatestFrom
: the source flow drives emissions, and only emits when all other flows have emitted at least once, using the latest values from each flow.Original prompt
💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.