我有一个代码块,使用ReactiveX的几个map语句将List [VideoDetails]块转换为VideoGrid:
feedService.loadVideoDetailsFeed(things) .map(new Func1<List<VideoDetails>, List<Video>>() { @Override public List<Video> call(List<VideoDetails> details) { return Lists.transform(details, new Function<VideoDetails, Video>() { @Override public Video apply(VideoDetails input) { return input.getVideo(); } }); } }) .map(new Func1<List<Video>, VideoGrid>() { @Override public VideoGrid call(List<Video> videos) { //stuff } })如您所见,我在其中一个map语句中使用Guava变换从List [VideoDetails]转到List [Video]。 我认为通过ReactiveX有更好的方法来完成这种转换? 我正在浏览文档的转换部分 ,但我可能对ReactiveX太过绿色以了解在这里使用的内容。
上面的代码片段有效,如果可能的话,我宁愿以正确的方式进行。
I have a block of code that transforms a block of List[VideoDetails] into a VideoGrid using a couple map statements with ReactiveX:
feedService.loadVideoDetailsFeed(things) .map(new Func1<List<VideoDetails>, List<Video>>() { @Override public List<Video> call(List<VideoDetails> details) { return Lists.transform(details, new Function<VideoDetails, Video>() { @Override public Video apply(VideoDetails input) { return input.getVideo(); } }); } }) .map(new Func1<List<Video>, VideoGrid>() { @Override public VideoGrid call(List<Video> videos) { //stuff } })As you can see, I'm using a Guava transform in one of the map statements to go from List[VideoDetails] to List[Video]. I would assume there is a better way through ReactiveX to accomplish this transformation? I was looking through the transforming section of the docs but I might be too green with ReactiveX to know what to use here.
The above code snippet works, I would just rather do it in the correct way if possible.
最满意答案
看起来你需要保持VideoInfo流的缓冲方面来创建VideoGrid。 因此,如果是这种情况,那么在整个过程中保持Rx的唯一方法就是不必要地将这些子列表转换为可观察对象,然后映射/转换内部可观察对象,仅在创建VideoGrid时将它们折叠回列表。 你现在这样做的方式可能是最务实的。
如果你碰巧使用Java 8,你可以抛弃Guava和内部类:
return details.stream().map(VideoDetails::getVideo).collect(Collectors.toList());编辑这是一种留在Rx的方法
feedService.loadVideoDetailsFeed(things) .flatMap(new Func1<List<VideoDetails>, Observable<List<Video>>>() { @Override public Observable<List<Video>> call(final List<VideoDetails> videoDeets) { return Observable.from(videoDeets).map(new Func1<VideoDetails, Video>() { @Override public Video call(final VideoDetails videoDetails) { return videoDetails.getVideo(); } }).toList(); } }) .map(new Func1<List<Video>, VideoGrid>() { @Override public VideoGrid call(List<Video> videos) { return VideoGrid.fromListOfVideos(videos); } });这是一种产生更少垃圾的方法。 实际的可观察查询更具可读性,但整体代码更多。
private static Func1<VideoDetails, Video> _getVideo = new Func1<VideoDetails, Video>() { @Override public Video call(final VideoDetails videoDetails) { return videoDetails.getVideo(); } }; private static Func1<List<VideoDetails>, Observable<List<Video>>> _mapVideoDetailsToVideos = new Func1<List<VideoDetails>, Observable<List<Video>>>() { @Override public Observable<List<Video>> call(final List<VideoDetails> videoDeets) { return Observable.from(videoDeets).map(_getVideo).toList(); } }; private static Func1<List<Video>, VideoGrid> _buildVideoGridFromVideos = new Func1<List<Video>, VideoGrid>() { @Override public VideoGrid call(List<Video> videos) { return VideoGrid.fromListOfVideos(videos); } }; private static void yourFunction(final VideoDeetsSource feedService, String things) { feedService.loadVideoDetailsFeed(things) .flatMap(_mapVideoDetailsToVideos) .map(_buildVideoGridFromVideos); }It looks like you need to keep the buffered aspect of the VideoInfo stream to create the VideoGrid. So if that's the case, then the only way to stay with Rx the whole way would be to needlessly turn those sublists into observables and then map/transform the inner observable, only to collapse them back to lists when you create the VideoGrid. The way you're doing it now is probably the most pragmatic.
If you happen to be using Java 8, you can ditch Guava and the inner class:
return details.stream().map(VideoDetails::getVideo).collect(Collectors.toList());Edit Here is a way to do it staying in Rx
feedService.loadVideoDetailsFeed(things) .flatMap(new Func1<List<VideoDetails>, Observable<List<Video>>>() { @Override public Observable<List<Video>> call(final List<VideoDetails> videoDeets) { return Observable.from(videoDeets).map(new Func1<VideoDetails, Video>() { @Override public Video call(final VideoDetails videoDetails) { return videoDetails.getVideo(); } }).toList(); } }) .map(new Func1<List<Video>, VideoGrid>() { @Override public VideoGrid call(List<Video> videos) { return VideoGrid.fromListOfVideos(videos); } });And here is a way that will generate less garbage. The actual observable query is more readable but it is more code overall.
private static Func1<VideoDetails, Video> _getVideo = new Func1<VideoDetails, Video>() { @Override public Video call(final VideoDetails videoDetails) { return videoDetails.getVideo(); } }; private static Func1<List<VideoDetails>, Observable<List<Video>>> _mapVideoDetailsToVideos = new Func1<List<VideoDetails>, Observable<List<Video>>>() { @Override public Observable<List<Video>> call(final List<VideoDetails> videoDeets) { return Observable.from(videoDeets).map(_getVideo).toList(); } }; private static Func1<List<Video>, VideoGrid> _buildVideoGridFromVideos = new Func1<List<Video>, VideoGrid>() { @Override public VideoGrid call(List<Video> videos) { return VideoGrid.fromListOfVideos(videos); } }; private static void yourFunction(final VideoDeetsSource feedService, String things) { feedService.loadVideoDetailsFeed(things) .flatMap(_mapVideoDetailsToVideos) .map(_buildVideoGridFromVideos); }更多推荐
发布评论