How to group and flatten data using DynamicData

77 views Asked by At

I have the following sourcecache object,

 private readonly SourceCache<PlainItinerary, string> _itineraries = new SourceCache<PlainItinerary, string>(itinerary => itinerary.ItineraryId);

and then I've grouped the itineraries by date.

_itineraries
    .Connect()
    .Group(k =>
    {
        if (k.JourneyStartTime.HasValue)
            return new DateTimeOffset(k.JourneyStartTime.Value.Date).ToUnixTimeMilliseconds();
        else
            return -1;
    })
    .Transform(group => new ItineraryGroup(group, Disposables))
    .Sort(SortExpressionComparer<ItineraryGroup>.Ascending(group => group.Date))
    .ObserveOn(MainThread.AppContext)
    .Bind(ItineraryGroups);

The above code stores the results in the following collection.

public ObservableCollectionExtended<ItineraryGroup> ItineraryGroups {get; set;}

The ItineraryGroup class is defined as follows,

public class ItineraryGroup : ObservableCollectionExtended<PlainItinerary>
{

}

and I have bound this collection the Xamarin.Forms CollectionView which supports grouping.

But now, I am converting the UI in Xamarin.Android which uses RecyclerView which needs a flat collection.

So, the above DynamicData code, I want to convert to the following structure with minimal changes,

public class ItineraryHeaderItem : BaseItem
{
    public DateTimeOffset Date {get; set;}
}

public class ItineraryItem : BaseItem
{
    public PlainItinerary Itinerary {get; set;}
}

public ObservableCollectionExtended<BaseItem> Itineraries {get; set;}

Does anybody have an idea how to do it? Thank you.

1

There are 1 answers

0
Pravin Patil On BEST ANSWER

Used TransformMany and Mege functions to solve the above issue,

_itineraries
    .Connect()
    .Group(k =>
    {
        if (k.JourneyStartTime.HasValue)
            return new DateTimeOffset(k.JourneyStartTime.Value.Date).ToUnixTimeMilliseconds();
        else
            return -1;
    })
    .TransformMany(k =>
    {
        BaseItineraryItem item = new ItineraryDateItem(k.Key, GuidUtil.GenerateGuid(k.Key.ToString(CultureInfo.InvariantCulture)), this);
        var obs = new ObservableCollection<BaseItineraryItem>() { item };
        var osbSet = obs.ToObservableChangeSet<BaseItineraryItem, string>(m => m.Id);

        var groupObservable = k.Cache
            .Connect();

        var disposable = groupObservable
            .Merge(osbSet)                        
            .Bind(out var items)
            .Subscribe();

        Disposables.Add(disposable);

        return items;
    }
    .Sort(SortExpressionComparer<BaseItineraryItem>.Ascending(item => item.Date))
    .ObserveOn(MainThread.AppContext)
    .Bind(ItineraryGroups);