RxJava:减少或合并或合并

时间:2015-07-11 20:54:44

标签: android rx-java

我想要查询Android ContentProvider的联系人。

Cursor返回包含一个联系人的多个重复项,在这些联系人中,他们可能有多个注册号码针对其contact_id注册。

到目前为止,我已经查询了数据库,并且正在迭代Cursor行。 我映射()这些行并将它们转换为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;

1 个答案:

答案 0 :(得分:3)

使用groupBy获取具有相同contactId的记录,然后flatMapreduce合并记录

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