2

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.

  • You almost have it write on the last line, your problem is the types. When you use `OrderBy` to sort an `ILookup` you are leveraging the fact that `ILookup` implements `IEnumerable>` via which `OrderBy` is provided. However, as you noted in your comments, lookups are immutable. Why are you trying to sort it in the first place? If you really need to there are some OK options but this feels like an X-Y Problem – Aluan Haddad Dec 28 '21 at 11:09
  • @AluanHaddad thank you, maybe you're right about the XY problem, I've got an other answer now, but perhaps I could also use the IOderedEnumberable> directy instead of the Lookup because of the mentioned type problem: `IOrderedEnumerable> lookupSortedBySortedList = lookupUnsorted.OrderBy( p => sortedList.IndexOf( p.Key ) );`. – Louise Delgado Dec 28 '21 at 13:56

1 Answers1

0

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);
pfx
  • 20,323
  • 43
  • 37
  • 57