Sergey Trukhachev
Sergey Trukhachev

Reputation: 538

How to sort RealmList objects using nested properties?

I've started to work with Realm and I'm curious if it's possible to sort RealmList object by nested properties.

I have some ListModel object:

public class ListModel extends RealmObject {

   @Required
   private String itemName;
   ...
   private RealmList<ItemModel> items;
   ...
}

ItemModel is:

public class ItemModel extends RealmObject {

   private TagModel tag;
   ...
   private boolean isBought = false;

   @PrimaryKey
   private long created;
   ...
}

TagModel is:

public class TagModel extends RealmObject {

   @PrimaryKey
   private String tagName;
   ...
   private CategoryModel category;
   ...
}

and CategoryModel is:

public class CategoryModel extends RealmObject {

   @PrimaryKey
   private int categoryType;
   ...
}

So, what I really need is to have something like this:

RealmResults<ItemModel> sortedItems= realm.where(ListModel.class)
            .equalTo("created", created)
            .findFirst().getItems().where().findAllSorted("isBought", Sort.ASCENDING, "tag.category.categoryType", Sort.ASCENDING, "tag.tagName", Sort.ASCENDING);

Is it possible to achieve this somehow? For this moment, as I understand, it's impossible to use following structure "tag.category.categoryType" for my needs.

As a temporary solution I'm thinking about the following approach:

ListModel listModel = realm.where(ListModel.class)
      .equalTo("created", created)
      .findFirst();

List<ItemModel> items = listModel.getItems();
Collections.sort(items, new Comparator<ItemModel>() {
      @Override
      public int compare(ItemModel lhs, ItemModel rhs) {
            // here some sorting logic
      }
});

But i'm not sure this is a correct way.

Upvotes: 2

Views: 2659

Answers (2)

Takao Sumitomo
Takao Sumitomo

Reputation: 511

Gonzalo's approach looks good for now. But it was kind of slow because accessing nested items causes I/O. In my case, It takes about 30 seconds with 10000 items. So I refined it to use cache.

Collections.sort(medicineClassList, new Comparator<MedicineClass>() {
    Map<String, String> primaryKey2SortKey = new HashMap();
    @Override
    public int compare(MedicineClass lmo, MedicineClass rmo) {
        String lmo_string = pullSortKey(lmo);
        String rmo_string = pullSortKey(rmo);
        return lmo_string.compareToIgnoreCase(rmo_string);
    }

    private String pullSortKey(MedicineClass item) {
        if (primaryKey2SortKey.containsKey(item.getPrimaryKey())) {
            return primaryKey2SortKey.get(item.getPrimaryKey());
        }
        String sortKey = item.getProduct_request().getProduct().getName();
        primaryKey2SortKey.put(item.getPrimaryKey(), sortKey);
        return sortKey;
    }
});

Upvotes: 1

Gonzalo Ledezma Torres
Gonzalo Ledezma Torres

Reputation: 140

I have the same problem and i solved this with the same way, using Collections on RealmList

My sort need to order alphabetically the names of a List that are on the RealmList nested in main object

//medicineClassList is a RealmList with some RealmObjects

Collections.sort(medicineClassList, new Comparator<MedicineClass>() {
    @Override
    public int compare(MedicineClass lmo, MedicineClass rmo) {
        String lmo_string = lmo.getProduct_request().getProduct().getName();
        String rmo_string = rmo.getProduct_request().getProduct().getName();

        return lmo_string.compareToIgnoreCase(rmo_string);
    }
});

So then i use medicineClassList in a custom adapter to set the ListView where i put the results

Hope this helps.

Upvotes: 0

Related Questions