RxJava: shrink or merge or merge

What I want to do is request the Android ContentProvider for contacts.

The return cursor contains multiple duplicates for a contact, in which they may have more than one number registered to their contact_id)

So far I have queried the DB and iterate over the lines in the cursor. I map () these strings and convert them to ValueObjects

Next, I want to go through the entire list of VOs and concatenate those with the same contact_id (VO will store an array of labels and numbers)

But I am stuck, I cannot figure out how to accomplish the last part, how can I iterate over the ValueObjects list, concatenating the duplicates into one and then removing the unnecessary ones.

This is a sample cursor returned by ContentProvider:

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
}

      

Function example

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;

      

+3


source to share


1 answer


Use groupBy

to get records with the same contactId

together and then flatMap

and reduce

to merge records



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

      

+3


source







All Articles