Split string into array and sort array

I am trying to sort a comma separated string. But he does not behave as expected

var classes = "10,7,8,9"; Console.Write(string.Join(",", classes.Split(',').OrderBy(x => x))); Console.ReadKey(); 

and conclusion

10,7,8,9

But I want the expected result to be as follows:

7,8,9,10

Classes may have a section with them. like 7a, 7b

and I want to achieve it on one line of code.

+5
source share
6 answers

You can use regex as follows

 var classes = "10,7,8,9"; Regex number = new Regex(@"^\d+"); Console.Write(string.Join(",", classes.Split(',').OrderBy(x => Convert.ToInt32(number.Match(x).Value)).ThenBy(x => number.Replace(x, "")))); Console.ReadKey(); 
+3
source

CODE:

 using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using System.Collections; namespace Rextester { public class Program { public static void Main(string[] args) { var l = new List<string> { "1D", "25B", "30A", "9C" }; l.Sort((b, a) => { var x = int.Parse(Regex.Replace(a, "[^0-9]", "")); var y = int.Parse(Regex.Replace(b, "[^0-9]", "")); if (x != y) return y - x; return -1 * string.Compare(a, b); }); foreach (var item in l) Console.WriteLine(item); } } } 

OUTPUT: 1D 9C 25V 30A

ONLINE COMPILE: http://rextester.com/CKKQK66159

+1
source

Use the following using -directive:

 using System.Text.RegularExpressions; 

And try the following:

 var input = "7,7a,8,9a,9c,9d,10"; var sorted = from sp in input.Split(',') let reg = Regex.Match(sp, @"(?<num>[0-9]+)(?<char>[az]*)", RegexOptions.IgnoreCase | RegexOptions.Compiled) let number = int.Parse(reg.Groups["num"].ToString()) orderby reg.Groups["char"].ToString() ascending // sort first by letter orderby number ascending // then by number select sp; var result = string.Join(",", sorted); Console.WriteLine(result); //output (tested): 7,7a,8,9a,9c,9d,10 

It uses a regular expression to determine the number and letter part of the input string. The regex pattern uses named groups, which are denoted as follows: (?<group_name> regex_expr ) .


Code complexity above: O(n log(n)) if you are concerned about large collections of numbers.

<h / "> Additional information on the named Regex groups.
Learn more about LINQ.
... and about orderby -clause.

+1
source

All on one line, also supports "4a", etc.

edit: when testing this line, such as 1,2,111,3 , will be displayed as 111,1,2,3 , so it may not be what you are looking for.

  string str = "1,2,3,4a,4b,5,6,4c"; str.Split(',').OrderBy(x => x).ToList().ForEach(x=> Console.WriteLine(x)); Console.ReadKey(); 
0
source

Here is my implementation:

 IEnumerable<Tuple<string, string[]>> splittedItems = items.Select(i => new Tuple<string, string[]>(i, Regex.Split(i, "([0-9]+)"))); List<string> orderedItems = splittedItems.OrderBy(t => Convert.ToInt16(t.Item2[1])) .ThenBy(t => t.Item2.Length > 1 ? t.Item2[2] : "1") .Select(t => t.Item1).ToList(); 
  • Separate input into numeric and non-digital characters
  • Save split lines with your parent line
  • Order by number
  • Then order using numeric characters
  • Take parent line again after sorting

The result is as required: { "10", "7", "8b", "8a", "9" } sorted by { "7", "8a", "8b", "9", "10" }

0
source

You sort the lines (in alphabetical order), so yes, "10" comes to "7".

My solution converts "10,7b, 8,7a, 9b" to "7a, 7b, 8,9b, 10" (first sort by integer prefix, then by the substring itself).

Helper method for parsing a string prefix:

 private static int IntPrefix(string s) => s .TakeWhile(ch => ch >= '0' && ch <= '9') .Aggregate(0, (a, c) => 10 * a + (c - '0')); 

Sort substrings by integer prefix, and then by the string itself:

 classes.Split(',') // string[] .Select(s => new { s, i = IntPrefix(s) }) // IEnumerable<{ s: string, i: int }> .OrderBy(si => si.i) // IEnumerable<{ s: string, i: int }> .ThenBy(si => si.s) // IEnumerable<{ s: string, i: int }> .Select(si => si.s) // IEnumerable<string> 

One liner (with string.Join ):

 var result = string.Join(",", classes.Split(',').Select(s => new {s, i = IntPrefix(s)}).OrderBy(si => si.i).ThenBy(si => si.s).Select(si => si.s)); 
0
source

Source: https://habr.com/ru/post/1270667/


All Articles