0

I have some large files (5000+ line items) with brief information of hardware parts.

Put simply, each part has an Id and name, and all parts from a file are added to a List collection, like:

void Main() { var parts = new List<dynamic>(); parts.Add(make(1, "Part A")); parts.Add(make(2, "Part B")); parts.Add(make(3, "Part C")); parts.Add(make(4, "Part D")); parts.Add(make(5, "Part A")); parts.Add(make(6, "Part E")); parts.Add(make(7, "Part B")); parts.Add(make(8, "Part F")); parts.Add(make(9, "Part G")); parts.Add(make(10, "Part B")); } dynamic make(int id, string name) { dynamic o = new ExpandoObject(); o.id = id; o.name = name; return o; } 

This list of parts is sorted, first by a custom sorting order of part Ids (determined separately) available as a List of Ids:

var customOrderPartIds = new List<int>() { 10, 8, 6, 4, 2, 9, 7, 5, 3, 1 }; parts.OrderBy(p => customOrderPartIds.IndexOf(p.id)).ToList(); 
/* This gives the needed order: 10 - Part B 8 - Part F 6 - Part E 4 - Part D 2 - Part B 9 - Part G 7 - Part B 5 - Part A 3 - Part C 1 - Part A */ 

Now, the second ordering I need is for same part names to be together, but keeping the first ordering intact, and a part group increment number:

/* This is the needed final order, along with an increment: 10 - Part B - 1 2 - Part B - 1 7 - Part B - 1 8 - Part F - 2 6 - Part E - 3 4 - Part D - 4 9 - Part G - 5 5 - Part A - 6 1 - Part A - 6 3 - Part C - 7 */ 

How can this be achieved?

9
  • 1
    Does this answer your question? LINQ OrderBy with more than one field Commented Jun 7, 2021 at 9:55
  • 1
    You can chain ordering by using OrderBy(e => e.Property).ThenBy(e => e.OtherProperty) Commented Jun 7, 2021 at 9:59
  • Thanks. Unfortunately, it doesn't help. If I use ThenBy and do something like parts.OrderBy(p => customOrderPartIds.IndexOf(p.id)).ThenBy(p => p.name).ToList();, the results don't reflect the second ordering as I need it (sample output above). Commented Jun 7, 2021 at 9:59
  • 2
    Why you use dynamic at all and not a class with a property Id and Name? Even a ValueTuple<int, id> was much better than dynamic. Commented Jun 7, 2021 at 10:02
  • 1
    @Nick: don't use dynamic to simplify your questions, that will raise other issues not related to your question then. Commented Jun 7, 2021 at 10:04

2 Answers 2

2

You could group it, and output again.

var result = parts.OrderBy(p => customOrderPartIds.IndexOf(p.id)) .GroupBy(x => x.name) .SelectMany(x => x); 
Sign up to request clarification or add additional context in comments.

1 Comment

Missing the increment number but it's simple to add
1

Something like that should do as second ordering:

parts = parts.SelectMany( item => parts.First(p => p.Name == item.Name) == item ? parts.Where(p => p.Name == item.Name) : new List<dynamic>()).ToList(); 

If it is the first one of the group: return all items of the group.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.