Skip to content

Extension functions for bulk collection operations #2357

Open
@Minirogue

Description

@Minirogue

I'm guessing the answer might be "if you need it, then you can write your own extension functions", but I was wondering if it might be worth adding suspend extension functions for Collection. For context, I've found myself recently using

val taskResults = someList.map {
    async {
        performSomeTask()
    }
}.awaitAll()

One could also reasonably use launch (and joinAll() if necessary) if the results of performSomeTask aren't needed. The general use case is "I want to perform a task on a collection of items asynchronously". I wrote my own extension function and I'm wondering if it is worth something like this being in the library itself:

suspend inline fun <T, R> Collection<T>.asyncMap(crossinline transform: suspend (T) -> R): List<Deferred<R>> =
    coroutineScope { map { async { transform(it) } } }

Naturally, there is some cleanup and due diligence needed: it should probably be on Iterable instead of Collection, it should probably take a CoroutineContext, maybe there should be a suspendMap or awaitMap that also calls awaitAll(), etc. Also, there's probably some other functions in addition to map that could use this treatment (zip?) if it is determined to be something worth adding to the library.

Everything I look at that seems related to this points to #172, which appears to potentially be at a dead-end, since actor has been marked with @ObsoleteCoroutinesApi and there has been no activity there since February 2019 (with the last linked issue in October 2019). Also, while digging to see if this has been brought up, it looks like I'm certainly not the first to come up with this solution: #1022. Also, that issue raises another reason for this to not be in the library: it could saturate the dispatcher if we're not careful.

Even so, I think it's a common enough use-case that it's worth bringing up. It might seem small, but it saves an indentation and I don't think it's any more trivial than awaitAll() or joinAll(), which have already initiated the idea of coroutine collection extension functions.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions