Here's an optimized version that requires only one LINQ statement:
string match = "384"; List<string> sNumbers = new List<string> {"34521", "38450", "138477", "38451", "28384", "13841", "12345"}; // That all it is var result = (from x in sNumbers group x by new { Start = x.StartsWith(match), Contain = x.Contains(match)} into g where g.Key.Start || g.Key.Contain orderby !g.Key.Start select g.OrderBy(Convert.ToInt32)).SelectMany(x => x); result.ToList().ForEach(x => Console.Write(x + " "));
Steps:
1.) Group g based on StartsWith and Contains
2.) Just select the groups that contain the match.
3.) Order the reverse key StartsWith (so that StartsWith = true appears before StartsWith = false)
4.) Select a sorted list of items in both groups
5.) Make flatMap (SelectMany) on both lists to get one final list of results
Here's a non-optimized version:
string match = "384"; List<string> sNumbers = new List<string> {"34521", "38450", "138477", "38451", "28384", "13841", "12345"}; var matching = from x in sNumbers where x.StartsWith(match) orderby Convert.ToInt32(x) select x; var nonMatching = from x in sNumbers where !x.StartsWith(match) && x.Contains(match) orderby Convert.ToInt32(x) select x; var result = matching.Concat(nonMatching); result.ToList().ForEach(x => Console.Write(x + " "));
source share