2016-02-23 24 views
0

我正在嘗試使用StackOverFlow API。我想要標籤列表名稱,數量和說明。問題是,描述返回不同的API函數:如何使用RxJava更改對象列表

https://api.stackexchange.com/2.2/tags?page=1&pagesize=3&order=desc&sort=popular&site=stackoverflow

給了我只有兩個3個所需的字段:(通過單擊鏈接嘗試):

  • 1)名稱
  • 2)計算

https://api.stackexchange.com/2.2/tags/javascript%3Bjava%3Bc%23/wikis?site=stackoverflow 需要標記名稱和給我:

  • 3)摘錄(介紹)

我建立了一個更新接口:

class Item { 
    @SerializedName("name") 
    public String name; 
    @SerializedName("count") 
    public String count; 
    @SerializedName("excerpt") 
    public String excerpt; 
} 

class Items { 
    @SerializedName("items") 
    public Item[] items; 
} 

@GET("/2.2/tags") 
Observable<Items> getItems(@Query("page") String page, 
          @Query("pagesize") String pagesize, 
          @Query("order") String order, 
          @Query("sort") String sort, 
          @Query("site") String site); 


@GET("/2.2/tags/{tagnames}/wikis") 
Observable<Items> getDescription(@Path("tagnames") String tagnames, 
             @Query("site") String site); 

因此,首先,我們應該執行getItems,然後讓所有的名稱和執行getDescription FUNC最後用新的領域把我們的物品弄混了。 所以我想收集所有3(名稱,計數和摘錄在一個可觀察的)。

這裏是我的觀察,到目前爲止:

App.getServerAPI() 
      .getItems("page", "pagesize", "order","sort", "site") //just example strings 
      .observeOn(AndroidSchedulers.mainThread()); 

我應該怎麼辦呢?我應該在兩個函數中使用Observable嗎?

UPDATE: 按照你的意見,我寫了一本至今:

public Observable<ServerAPI.Tags> call() { 
         return App.getServerAPI() 
           .getItems("page", "pagesize", "order", "sort", "site") 
           .map(new Func1<ServerAPI.Tags, ServerAPI.Tags>() { 
            @Override 
            public ServerAPI.Tags call(ServerAPI.Tags tags) { 
             String tagsStr = ""; 
             for (ServerAPI.Tag tag: tags.items){ 
              tagsStr +=tag.name+";"; 
             } 
             ServerAPI.Excerts excerts = App.getServerAPI(). 
               getExcerts(tagsStr, "site"); 
             for (ServerAPI.Excert excertItem : excerts.items){ 
              for (ServerAPI.Tag tagItem: tags.items){ 
               if (excertItem.tag_name.equals(tagItem.name)){ 
                tagItem.excerpt = excertItem.excerpt; 
               } 
              } 
             } 
             return tags; 
            } 
           }) 
           .delay(1, TimeUnit.SECONDS) 
           .observeOn(AndroidSchedulers.mainThread()); 

        } 

看起來該死的醜陋!

+0

你必須創建一個Observable,使a。2個可觀察到的郵編, 完成後,你有2個結果,並與2個結果創建的名稱,計數和摘錄 – xanexpt

回答

0

你可以改變getDescription方法來自:

Observable<Items> getDescription(@Path("tagnames") String tagnames, 
             @Query("site") String site); 

DescriptionResponse getDescription(@Path("tagnames") String tagnames, 
             @Query("site") String site); 

其中DescriptionResponse代表響應對象:

public class DescriptionResponse { 
    List<DescriptionItem> items; 
} 

然後得到項目和使用map運營商提供的說明和地圖他們到您的項目:

api.getItems("", "", "", "", "").map(items -> { 
    String tags = "";//iterate over items and grab all tags 
    DescriptionResponse description = api.getDescription(tags, ""); 
    //iterate over items and descriptions in response and set appropriate description 
    return items; 
}).subscribe(items -> { 
    //here is your items with descriptions 
}); 
1

我會做這樣的:

class Tag{ 
    public String name; 
    public String count; 
} 

class TagList { 
    public List<Tag> tags; 
} 

class Excert { 
    public String excert; 
} 

class Item { 
    public final String name; 
    public final String count; 
    public final String excert; 

    public Item(String name, String count, String excert) { 
     this.name = name; 
     this.count = count; 
     this.excert = excert; 
    } 
} 

Observable<TagList> getItems() {} 

Observable<Excert> getExcert(String tagName) {} 


public void testFlatMap() { 
    getItems() 
      //iterate over each Tag 
      .flatMap(tagList -> Observable.from(tagList.tags)) 
      //call server for excert 
      .flatMap(tag -> getExcert(tag.name), 
        new Func2<Tag, Excert, Item>() { 
         @Override 
         public Item call(Tag tag, Excert excert) { 
          //compose final data structure 
          return new Item(tag.name, tag.count, excert.excert); 
         } 
        }) 
      //item here 
      .subscribe(item -> { 

      }); 
} 

更新

這裏是例如調用的API的標籤列表。

class Tag { 
    public String name; 
    public String count; 
} 

class TagList { 
    public List<Tag> tags; 
} 

class Excert { 
    public String excert; 
    public String tagName; 
} 

class ExcertResponse { 
    public List<Excert> items; 
} 

class Item { 
    public final String name; 
    public final String count; 
    public final String excert; 

    public Item(String name, String count, String excert) { 
     this.name = name; 
     this.count = count; 
     this.excert = excert; 
    } 
} 

Observable<TagList> getItems() { 
    return Observable.empty(); 
} 

Observable<ExcertResponse> getExcert(String tagName) { 
    return Observable.empty(); 
} 

private String constructTagsList(Map<String, Tag> stringTagMap) { 
    StringBuilder builder = new StringBuilder(); 
    for (String tagName : stringTagMap.keySet()) { 
     if (builder.length() != 0) { 
      builder.append(";"); 
     } 
     builder.append(tagName); 
    } 
    return builder.toString(); 
} 

public void testFlatMap() { 
    getItems() 
      //create map in order to easily find tag 
      .map(tagList -> { 
       Map<String, Tag> map = new HashMap<String, Tag>(tagList.tags.size()); 
       for (Tag tag : tagList.tags) { 
        map.put(tag.name, tag); 
       } 
       return map; 
      }) 
      .flatMap(stringTagMap -> { 
         String tagsList = constructTagsList(stringTagMap); 
         return getExcert(tagsList); 
        }, 
        new Func2<Map<String, Tag>, ExcertResponse, List<Item>>() { 
         @Override 
         public List<Item> call(Map<String, Tag> stringTagMap, ExcertResponse response) { 
          List<Item> items = new ArrayList<Item>(stringTagMap.size()); 
          for (Excert excert : response.items) { 
           Tag tag = stringTagMap.get(excert.tagName); 
           Item item = new Item(tag.name, tag.count, excert.excert); 
           items.add(item); 
          } 
          return items; 
         } 
        }) 
      //List of items here 
      .subscribe(item -> { 

      }); 
} 
+0

我覺得這個方法是非常慢,並沒有使用Stackoverflow的所有功能api:/2.2/tags/javascript;java;c#/wikis?site=stackoverflow - 我們最多可以放置20個標籤 –

+0

@FixedGear我試圖展示如何使用'rxJava'鏈接多個API調用。如果你不想遍歷每個標籤,那麼不要這樣做。相反,應用'map' /'flatMap'來創建任何其他有效的輸入參數。或者在'getExcert'調用之前直接進行。 – MyDogTom

+0

您能否通過擴展您的答案來描述方法? –