2

I have a LINQ query that gets me all results where the code is contained within a list. This works fine, however I need to keep the order as per the list of codes. So when the EnumerableRowCollection is returned, the rows are in the same order as tehy were in the List.

Here's my current code:

if (productcodes != "")
{
    string[] pcodes = productcodes.Split('|');

    // Get most recently viewed first
    Array.Reverse(pcodes);

    List<int> prodCodes = new List<int>();

    foreach (string pc in pcodes)
    {
        if (pc != "")
        {
            prodCodes.Add(Convert.ToInt32(pc));
        }
    }

    results = results.Where(d => d["ProductCode"] != DBNull.Value && (int)d["ID"] > 0 && prodCodes.Contains((int)d["ProductCode"])).Select(d => d);
}

So I need the EnumerableRowCollection results to be ordered the same as they are in List prodCodes rather than it's own random order.

Any ideas?

Omar
  • 16,329
  • 10
  • 48
  • 66
dhardy
  • 993
  • 2
  • 11
  • 22
  • Provides information on how LINQ affects order: http://stackoverflow.com/questions/204505/preserving-order-with-linq – vossad01 Oct 19 '12 at 14:08
  • Use `var prodCodes = pcodes.ToList().Reverse();` to create a reversed list using an array. – Omar Oct 19 '12 at 14:13

2 Answers2

3

This is all you need:

IEnumerable<int> pcodes = productcodes.Split('|')
   .Where(s => !string.IsNullOrWhiteSpace(s))
   .Select(s => int.Parse(s))
   .Reverse();

var result = from code in pcodes
             join row in results on code equals row.Field<int>("ProductCode")
             select row;

The join at the end is in the order of the first sequence(the pcodes) and only containing ProductCodes are joined on an "inner join".

Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
1

Assuming the prodCodes are unique, you can project them into a mapping:

Dictionary<int, int> orderMap = prodCodes
  .Select( (val, i) => new {val, i} )
  .ToDictionary(x => x.val, x => x.i);

Then you can use the orderMap to order the result:

var results = GetSomeResults();
results = results.OrderBy(row => orderMap[(int)row["ProductCode"]]);
Amy B
  • 108,202
  • 21
  • 135
  • 185