Home > Software engineering >  Sort a Lookup by a given List
Sort a Lookup by a given List

Time:12-28

How can I sort the keys of an ILookup like the values from a given list in C#?
I found this two links, but didn't understand how to do it.
How to sort a lookup?
Sort a list from another list IDs

static void Main()
        {
            // list with category ids (order is given by internal logic)
            List<long> sortedList = new List<long> { 533, 321, 752, 251, 985 };

            // create the lookup with CategoryId as Key for the products
            // lookup already exists in original code and is needed before and after the reordering
            List<Product> products = new List<Product>();
            products.Add( new Product { Id = 23, CategoryId = 752 } );
            products.Add( new Product { Id = 24, CategoryId = 752 } );
            products.Add( new Product { Id = 25, CategoryId = 533 } );
            products.Add( new Product { Id = 26, CategoryId = 321 } );
            products.Add( new Product { Id = 27, CategoryId = 321 } );

            ILookup<long, Product> lookupUnsorted = products.ToLookup( prod => prod.CategoryId, prod => prod );

            // how can I sort the lookup, that the keys are sorted like in the sortedList?

            // I tried something like that (which gets a converting error)
            ILookup<long, Product> lookupSortedBySortedList = lookupUnsorted
                .OrderBy( p => sortedList.IndexOf( p.Key ) ).ToLookup( prod => prod.Key, prod => prod );

            // I also thought about iterating over the sortedList
            // and add the items from the existing lookupUnsorted to a new Lookup, but it's not possible to add items to a lookup
            // or with LINQ or the help of Join?
}

class Product
    {
        public long Id { get; set; }
        public long CategoryId { get; set; }
    }

Thanks.

CodePudding user response:

To sort, Join sortedList with lookupUnsorted,
then flatten the IGrouping instances within lookupUnsorted via SelectMany
and apply a new ToLookup.

var lookupSortedBySortedList = sortedList
    .Join(lookupUnsorted,
        categoryId => categoryId,
        groupOfProducts => groupOfProducts.Key,
        (categoryId, groupOfProducts) => groupOfProducts
    )
    .SelectMany(groupOfProducts => groupOfProducts)
    .ToLookup(product => product.CategoryId, product => product);

Alternatively, continuing on your attempt using OrderBy, that might look like below.

var lookupSortedBySortedList = lookupUnsorted
   .OrderBy(groupOfProducts => sortedList.IndexOf(groupOfProducts.Key))
   .SelectMany(groupOfProducts => groupOfProducts)
   .ToLookup(product => product.CategoryId, product => product);
  • Related