2016-04-08 142 views
1

假设我有3个长度不同的数组。不同尺寸的RxJava marge阵列

String[] array1 = new String{"1", "2", "3", "4"}; 
String[] array2 = new String{"1", "b", "c"}; 
String[] array3 = new String{"@", "#"}; 

我想合并他们得到以下结果:

{"1", "a", "@", "2", "b", "#", "3", "c", "4"} 

是否有可能与RxJava做到这一点?如果不是,你会建议什么其他解决方案? P.S.数组不能以任何不同的长度。

+3

一个简单的算法应该做的伎俩。在这个任务中我没有看到任何可以从RxJava的功能中受益的任何东西。 – laune

回答

1

如果你真的想与RxJava要做到这一点,这里是我会怎么做:

public class RoundRobinCollector { 
    public static void main(String[] args) { 
     Observable<Object> o1 = Observable.just("1", "2", "3", "4"); 
     Observable<Object> o2 = Observable.just("a", "b", "c"); 
     Observable<Object> o3 = Observable.just("@", "#"); 

     Object tag = new Object(); 
     Observable<Object> otag = Observable.just(tag); 

     Observable<Object> p1 = o1.concatWith(otag.repeat()); 
     Observable<Object> p2 = o2.concatWith(otag.repeat()); 
     Observable<Object> p3 = o3.concatWith(otag.repeat()); 

     Observable.zip(p1, p2, p3, (a, b, c) -> { 
      List<Object> list = new ArrayList<>(); 
      if (a != tag) { 
       list.add(a); 
      } 
      if (b != tag) { 
       list.add(b); 
      } 
      if (c != tag) { 
       list.add(c); 
      } 
      return list; 
     }) 
     .takeWhile(list -> !list.isEmpty()) 
     .concatMapIterable(v -> v) 
     .toList() 
     .subscribe(System.out::println) 
     ; 
    } 
} 

鉴于原始来源可观,我垫在他们年底成为“无限”,因而有出现“长度相等”。我将它们压缩并在函数中,我从那些没有填充的列中准备一个列表。如果结束列表为空,则takeWhile将完成序列。然后我用concatMapIterable将序列平坦化,将它收集到列表中并打印结果。

+0

非常感谢您的回答。用Rx做这件事似乎比用简单的算法做起来要复杂得多。我只是觉得在Rx中可能有这样一个功能。但是因为我原来的问题与RxJava解决这个问题的方式有关,所以我接受这个答案是正确的。 – Andranik

0

通过答案akarnokd是正确的答案,如果你想解决RxJava这个问题,但我结束了一个简单的算法,像劳瑞懒懒建议,与RxJava变得更加复杂,这是原因。我只是认为RxJava可以具有某种功能,可以为我做到这一点。所以这里是我最后做的:

private List<Item> mergeItems(Response response){ 
     ArrayList<Item> mergedList = new ArrayList<>(); 

     final int eSize = response.getEvents().size(); 
     final int cSize = response.getCommunities().size(); 
     final int vSize = response.getVenues().size(); 

     final int maxSize = Math.max(eSize, Math.max(cSize, vSize)); 

     for (int i = 0; i < maxSize; i++){ 

      if(i < eSize){ 
       mergedList.add(response.getEvents().get(i)); 
      } 

      if(i < cSize){ 
       mergedList.add(response.getCommunities().get(i)); 
      } 

      if(i < vSize){ 
       mergedList.add(response.getVenues().get(i)); 
      } 
     } 

     return mergedList; 
    }