{"action":"created","issue":{"url":"https://api.github.com/repos/ReactiveX/RxJava/issues/5685","repository_url":"https://api.github.com/repos/ReactiveX/RxJava","labels_url":"https://api.github.com/repos/ReactiveX/RxJava/issues/5685/labels{/name}","comments_url":"https://api.github.com/repos/ReactiveX/RxJava/issues/5685/comments","events_url":"https://api.github.com/repos/ReactiveX/RxJava/issues/5685/events","html_url":"https://github.com/ReactiveX/RxJava/issues/5685","id":267505376,"number":5685,"title":"New operator for recursive concatenation","user":{"login":"gabrielhuff","id":19377340,"avatar_url":"https://avatars2.githubusercontent.com/u/19377340?v=4","gravatar_id":"","url":"https://api.github.com/users/gabrielhuff","html_url":"https://github.com/gabrielhuff","followers_url":"https://api.github.com/users/gabrielhuff/followers","following_url":"https://api.github.com/users/gabrielhuff/following{/other_user}","gists_url":"https://api.github.com/users/gabrielhuff/gists{/gist_id}","starred_url":"https://api.github.com/users/gabrielhuff/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gabrielhuff/subscriptions","organizations_url":"https://api.github.com/users/gabrielhuff/orgs","repos_url":"https://api.github.com/users/gabrielhuff/repos","events_url":"https://api.github.com/users/gabrielhuff/events{/privacy}","received_events_url":"https://api.github.com/users/gabrielhuff/received_events","type":"User","site_admin":false},"labels":[{"id":480313802,"url":"https://api.github.com/repos/ReactiveX/RxJava/labels/2.x","name":"2.x","color":"af40af","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2017-10-22T22:44:34Z","updated_at":"2017-10-24T16:47:58Z","closed_at":null,"author_association":"NONE","body":"How about this new operator (writing API in kotlin for readability):\r\n\r\n```kotlin\r\nfun <T> Single<T>.link(next: (T) -> Single<T>?) : Flowable<T>\r\n```\r\n\r\n**TL;DR:** It's basically a recursive `concat`.\r\n\r\nSay you have a finite sequence of `Singles` `s1`, `s2`, `s3`, …, `sn`. The elements emitted by all singles can be concatenated by calling `concat(s1, s2, s3, ..., sn)`. However, there are scenarios in which `s2` depends on the value emitted by `s1`, `s3` depends on the value emitted by `s2` and so on.\r\n\r\nThe `link` operator would be used to concatenate sequences whose consecutive singles can be calculated as function of their predecessor's emitted value:\r\n\r\n```\r\nRECEIVER: --A1\r\n\r\nOPERATOR: link { A(i) -> --A(i+1) }\r\n\r\nOUTPUT:   --A1--A2--A3--A4--A5-|\r\n```\r\n\r\nReturning `null` would mean that the sequence is over. It would be equivalent to:\r\n\r\n```kotlin\r\nfun <T> Single<out T>.link(next: (T) -> Single<out T>?) : Flowable<T> {\r\n    return flatMapPublisher { Flowable.concat(\r\n            Flowable.just(it),\r\n            next(it)?.link(next) ?: Flowable.empty()\r\n    ) }\r\n}\r\n```\r\n\r\nA typical use case would be consuming paginated data:\r\n\r\n```kotlin\r\nval elements = service.getFirstPage()\r\n            .link { it.nextPage }\r\n            .flatMap { Flowable.fromIterable(it.items) }\r\n```\r\n\r\nI created a single file [demo app](https://github.com/gabrielhuff/rx-pagination-demo) (the operator definition can be found [here](https://github.com/gabrielhuff/rx-pagination-demo/blob/master/src/main/kotlin/main.kt#L65-L70) and the usage [here](https://github.com/gabrielhuff/rx-pagination-demo/blob/master/src/main/kotlin/main.kt#L24))"},"comment":{"url":"https://api.github.com/repos/ReactiveX/RxJava/issues/comments/339056213","html_url":"https://github.com/ReactiveX/RxJava/issues/5685#issuecomment-339056213","issue_url":"https://api.github.com/repos/ReactiveX/RxJava/issues/5685","id":339056213,"user":{"login":"gabrielhuff","id":19377340,"avatar_url":"https://avatars2.githubusercontent.com/u/19377340?v=4","gravatar_id":"","url":"https://api.github.com/users/gabrielhuff","html_url":"https://github.com/gabrielhuff","followers_url":"https://api.github.com/users/gabrielhuff/followers","following_url":"https://api.github.com/users/gabrielhuff/following{/other_user}","gists_url":"https://api.github.com/users/gabrielhuff/gists{/gist_id}","starred_url":"https://api.github.com/users/gabrielhuff/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gabrielhuff/subscriptions","organizations_url":"https://api.github.com/users/gabrielhuff/orgs","repos_url":"https://api.github.com/users/gabrielhuff/repos","events_url":"https://api.github.com/users/gabrielhuff/events{/privacy}","received_events_url":"https://api.github.com/users/gabrielhuff/received_events","type":"User","site_admin":false},"created_at":"2017-10-24T16:47:58Z","updated_at":"2017-10-24T16:47:58Z","author_association":"NONE","body":"Ok, thanks for the answer. You can close this issue now."}}
{"actor":{"display_login":"gabrielhuff"}}