【问题标题】:RxJava: Reduce or Combine or MergeRxJava:减少或合并或合并
【发布时间】:2015-07-11 20:54:43
【问题描述】:

我想做的是在 Android ContentProvider 中查询联系人。

光标返回包含一个联系人的多个重复项,其中可能有多个针对其contact_id 注册的号码)

到目前为止,我已经查询了数据库,并且正在遍历光标行。 我 map() 这些行并将它们转换为 ValueObjects

接下来我要遍历所有的 VO 列表并合并具有相同 contact_id 的那些(VO 将存储一个标签和数字数组)

但是,我被卡住了,我不知道如何执行最后一部分,如何循环遍历 ValueObjects 列表,将重复项合并为一个,然后处理不需要的项。

这是 ContentProvider 返回的 Cursor 示例:

86 {
    _id=5190
    contact_id=2167
    display_name=John Doe
    data1=+44 20 7123 7890
    data2=3
    data3=null
    photo_thumb_uri=content://com.android.contacts/contacts/2167/photo
    lookup=731i7g4b3e9879f40515
}
87 {
    _id=5191
    contact_id=2167
    display_name=John Doe
    data1=+44 7967 123 789
    data2=2
    data3=null
    photo_thumb_uri=content://com.android.contacts/contacts/2167/photo
    lookup=731i7g4b3e9879f40515
}
88 {
    _id=5192
    contact_id=2167
    display_name=John Doe
    data1=+44 208 123 7890
    data2=1
    data3=null
    photo_thumb_uri=content://com.android.contacts/contacts/2167/photo
    lookup=731i7g4b3e9879f40515
}

函数示例

public static Observable<List<ContactVO>> fetchAllContacts(final Context context) {
    allContactsQuery(context);
    return ContentObservable.fromCursor(allContactsQuery(context))

            .map(mapToContactVO())

            .toList()

            // I am stuck
}

private static Cursor allContactsQuery(Context context) {
    final String[] CONTACTS = new String[]{
            Phone._ID,                     //.....0
            Phone.CONTACT_ID,              //.....1
            Contacts.DISPLAY_NAME_PRIMARY, //.....2
            Phone.NUMBER,                  //.....3
            Phone.TYPE,                    //.....4
            Phone.LABEL,                   //.....5
            Contacts.PHOTO_THUMBNAIL_URI,  //.....6
            Contacts.LOOKUP_KEY,           //.....7
    };

    String SELECTION = Contacts.DISPLAY_NAME_PRIMARY +
            "<>''" + " AND " + Contacts.IN_VISIBLE_GROUP + "=1" +
            " AND " + Contacts.HAS_PHONE_NUMBER + "=1";
    final String[] SELECTION_ARGS = null;
    final String SORT_ORDER = Contacts.SORT_KEY_PRIMARY;

    Cursor cursor = context.getContentResolver().query(
            Phone.CONTENT_URI,
            CONTACTS,
            SELECTION,
            SELECTION_ARGS,
            SORT_ORDER);
    return cursor;
}

@NonNull
private static Func1<Cursor, ContactVO> mapToContactVO() {
    return cursor -> {
        int len = cursor.getCount();

        final ContactVO contact = new ContactVO();
        contact.contactId = cursor.getString(CONTACT_ID);
        contact.displayName = cursor.getString(DISPLAY_NAME);
        contact.photoThumbnailUri = cursor.getString(PHOTO_THUMBNAIL_URI);
        contact.lookUp = cursor.getString(LOOK_UP);
        contact.addData(
                new Pair<String, String>(
                        cursor.getString(PHONE_TYPE),
                        cursor.getString(PHONE_NUMBER)
                )
        );
        return contact;
    };
}

public final static int CONTACT_ID = 1;
public final static int DISPLAY_NAME = 2;
public final static int PHONE_NUMBER = 3;
public final static int PHONE_TYPE = 4;
public final static int PHONE_LABEL = 5;
public final static int PHOTO_THUMBNAIL_URI = 6;
public final static int LOOK_UP = 7;

【问题讨论】:

  • 为什么这么复杂?请参阅stackoverflow.com/a/26820544/2252830,了解如何在一次迭代中获取所有电话和电子邮件
  • 因为我想玩 Rx 并想了解如何做到这一点:)

标签: android rx-java


【解决方案1】:

使用groupBy 将具有相同contactId 的记录放在一起,然后使用flatMapreduce 合并记录

ContentObservable.fromCursor(allContactsQuery(context))
    .map(mapToContactVO())
    .groupBy(contact -> contact.contactId)
    .flatMap(g -> g.reduce(mergeContacts()));

【讨论】:

  • 工作得很好,我什至尝试过.groupBy(),但不知道之后我需要做什么,谢谢
  • 很高兴听到,不用担心
猜你喜欢
  • 2017-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-27
  • 2015-05-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多