I have a string variable that contain [l=9;f=0;r=5;p=2]. There are may be a more than one:[l=9;f=0;r=5;p=2],[l=9;f=0;r=6;p=2].
I want to get List of Tuple<int,int,int>, where item1 = value of l, item2= value of r, item3=value of p. What is best approach to do this?
My code:
// split string
var splittedFormatedSeats = Regex.Matches(formatSeats, #"\[.+?\]")
.Cast<Match>()
.Select(m => m.Value)
.ToList();
IList<Tuple<int,int,int>> fullSeat = new List<Tuple<int, int, int>>();
foreach (var splittedFormatedSeat in splittedFormatedSeats)
{
...
}
Thanks.
I would adopt another strategy. First, split subcomponents of your string
var components = formatSeats.Split(',');
This will give you an array of string. This will be far more efficient to parse small chunks of strings instead of a big string.
You can then use either a Regex to extract the values or a simple code like this :
foreach(var component in components)
{
var parts = component.Trim("[]".ToCharArray()).Split(';');
}
var results = from component in components
let c = component.Trim("[]".ToCharArray())
.Split(';')
.Select(c=>int.Parse(c.SubString(2))
select new { l = c[0], f=c[1], r=c[2], p = c[3] };
This will produces an enumeration of an anonymous type.
foreach(var x in results)
{
Console.WriteLine("{0} / {1} / {2} / {3}", x.l, x.f, x.r, x.p);
}
If you actually need a Tuple simply change the code to :
var results = from component in components
let c = component.Trim("[]".ToCharArray())
.Split(';')
.Select(c=>int.Parse(c.SubString(2))
select new Tuple<int,int,int,int>{ l = c[0], f=c[1], r=c[2], p = c[3] };
I would however, advocate for writing a small struct to simplify the code and raise its readability.
public struct MyValue
{
private readonly int m_L;
public int L { get {return m_L; } }
private readonly int m_F;
public int F { get {return m_F; } }
private readonly int m_R;
public int R { get {return m_R; } }
private readonly int m_P;
public int P { get {return m_P; } }
public MyValue(int l, int f, int r, int p)
{
m_L = l;
m_F = f;
m_R = r;
m_P = p;
}
}
....
var results = from component in components
let c = component.Trim("[]".ToCharArray())
.Split(';')
.Select(c=>int.Parse(c.SubString(2))
select new MyValue(c[0],c[1],c[2],c[3]);
Finally, if the string always have this form, you could avoid using the Regex.
string formattedString = "[l=9;f=0;r=5;p=2],[l=9;f=0;r=6;p=2]";
var splitString = formattedString.Split(',')
.Select(p => p.Trim(new char[]{'[',']',' '}));
List<Tuple<int, int, int, int>> tupleList = new List<Tuple<int, int, int, int>>();
foreach (var item in splitString)
{
int[] finalSplit = item.Split(';').Select(p =>
Convert.ToInt32(p.Substring(p.LastIndexOf('=')+1).Trim())
).ToArray();
tupleList.Add(new Tuple<int, int, int, int>(finalSplit[0], finalSplit[1],
finalSplit[2], finalSplit[3]));
}
This will split values of l, f, r and p and add them to the Tuple.
Is the format of your inner string always the same ?
Is it always a single digit value for each variable (l, f, r & p)?
If so you can just substring them out.
foreach(var splittedFormatedSeat in splittedFormatedSeats)
{
int x, y, z;
string s = splittedFormatedSeat .ToString();
if(int.TryParse(s[3].ToString(), out x) &&
int.TryParse(s[11].ToString(), out y) &&
int.TryParse(s[15].ToString(), out z))
fullSeat.Add(new Tuple<int,int,int>(x,y,z));
}
Related
I need to sort a List<string> following 2 rules.
My string element will always be formatted as XXXnnnnE or XXXnnnnD where X are capitalized letters from A to Z and n are digit from 0 to 9.
I want to sort my list alphabetically, but I want E string to come before D string as shown below
DFG0001D
AWK0007E
ORK0127E
AWK0007D
DFG0001E
ORK0127D
need to be sorted as
AWK0007E
AWK0007D
DFG0001E
DFG0001D
ORK0127E
ORK0127D
How could I achieve this ?
Thanks for help
Here is snippet how you can do this with Linq OrderBy and ThenByDescending operations:
string[] arr = { "DFG0001D", "AWK0007E", "ORK0127E", "AWK0007D", "DFG0001E", "ORK0127D" };
arr = arr
.OrderBy(r => r.Substring(0, 7))
.ThenByDescending(s => s.Substring(7, 1))
.ToArray();
you can use a custom delegate and compare the 1st 3 chars and the last one:
List<string> x = new List<string>();
x.Add("DFG0001D");
x.Add("AWK0007E");
x.Add("ORK0127E");
x.Add("AWK0007D");
x.Add("DFG0001E");
x.Add("ORK0127D");
x.Sort(delegate(string c1, string c2) {
string a = c1.Substring(0, 3)+c1.Substring(c1.Length-1, 1);
string b = c2.Substring(0, 3)+c2.Substring(c2.Length-1, 1);
return (a.CompareTo(b));
});
Console.WriteLine("After sort...");
foreach (string i in x)
{
Console.WriteLine(i);
}
Fiddle example : https://dotnetfiddle.net/YAzvB4
var list = new List<string>{
"DFG0001D",
"AWK0007E",
"ORK0127E",
"AWK0007D",
"DFG0001E",
"ORK0127D"
};
list.Sort((str1, str2) => {
var eq = string.Compare(str1.Substring(0, str1.Length - 1), str2.Substring(0, str2.Length - 1));
if (eq == 0)
eq = string.Compare(str2[str2.Length - 1].ToString(), "E");
return eq;
});
foreach (var str in list)
Console.WriteLine(str);
Output:
AWK0007E
AWK0007D
DFG0001E
DFG0001D
ORK0127E
ORK0127D
just implement your own comparer like this:
class CustomStringComparer : IComparer<string>
{
private readonly IComparer<string> _baseComparer;
public CustomStringComparer(IComparer<string> baseComparer)
{
_baseComparer = baseComparer;
}
public int Compare(string x, string y)
{
// strings are completely same
if (_baseComparer.Compare(x, y) == 0)
{
return 0;
}
// strings are completely same except last char
if (_baseComparer.Compare(x.Substring(0, x.Length - 2), y.Substring(0, y.Length - 2)) == 0)
{
// if last char is E then win
return x.Last() == 'E' ? -1 : 1;
}
// defaut compare everything else
return _baseComparer.Compare(x, y);
}
}
Then you are able doing this:
static void Main(string[] args)
{
List<string> list = new List<string>()
{
"DFG0001D",
"AWK0007E",
"ORK0127E",
"AWK0007D",
"DFG0001E",
"ORK0127D"
};
list.Sort(new CustomStringComparer(StringComparer.CurrentCulture));
foreach (var item in list)
{
Console.WriteLine(item);
}
}
And output is this:
AWK0007E
AWK0007D
DFG0001E
DFG0001D
ORK0127E
ORK0127D
I have a text file that contains Values in this Format: Time|ID:
180|1
60 |2
120|3
Now I want to sort them by Time. The Output also should be:
60 |2
120|3
180|1
How can I solve this problem? With this:
var path = #"C:\Users\admin\Desktop\test.txt";
List<string> list = File.ReadAllLines(path).ToList();
list.Sort();
for (var i = 0; i < list.Count; i++)
{
Console.WriteLine(list[i]);
}
I got no success ...
3 steps are necessary to do the job:
1) split by the separator
2) convert to int because in a string comparison a 6 comes after a 1 or 10
3) use OrderBy to sort your collection
Here is a linq solution in one line doing all 3 steps:
list = list.OrderBy(x => Convert.ToInt32(x.Split('|')[0])).ToList();
Explanation
x => lambda expression, x denotes a single element in your list
x.Split('|')[0] splits each string and takes only the first part of it (time)
Convert.ToInt32(.. converts the time into a number so that the ordering will be done in the way you desire
list.OrderBy( sorts your collection
EDIT:
Just to understand why you got the result in the first place here is an example of comparison of numbers in string representation using the CompareTo method:
int res = "6".CompareTo("10");
res will have the value of 1 (meaning that 6 is larger than 10 or 6 follows 10)
According to the documentation->remarks:
The CompareTo method was designed primarily for use in sorting or alphabetizing operations.
You should parse each line of the file content and get values as numbers.
string[] lines = File.ReadAllLines("path");
// ID, time
var dict = new Dictionary<int, int>();
// Processing each line of the file content
foreach (var line in lines)
{
string[] splitted = line.Split('|');
int time = Convert.ToInt32(splitted[0]);
int ID = Convert.ToInt32(splitted[1]);
// Key = ID, Value = Time
dict.Add(ID, time);
}
var orderedListByID = dict.OrderBy(x => x.Key).ToList();
var orderedListByTime = dict.OrderBy(x => x.Value).ToList();
Note that I use your ID reference as Key of dictionary assuming that ID should be unique.
Short code version
// Key = ID Value = Time
var orderedListByID = lines.Select(x => x.Split('|')).ToDictionary(x => Convert.ToInt32(x[1]), x => Convert.ToInt32(x[0])).OrderBy(x => x.Key).ToList();
var orderedListByTime = lines.Select(x => x.Split('|')).ToDictionary(x => Convert.ToInt32(x[1]), x => Convert.ToInt32(x[0])).OrderBy(x => x.Value).ToList();
You need to convert them to numbers first. Sorting by string won't give you meaningful results.
times = list.Select(l => l.Split('|')[0]).Select(Int32.Parse);
ids = list.Select(l => l.Split('|')[1]).Select(Int32.Parse);
pairs = times.Zip(ids, (t, id) => new{Time = t, Id = id})
.OrderBy(x => x.Time)
.ToList();
Thank you all, this is my Solution:
var path = #"C:\Users\admin\Desktop\test.txt";
List<string> list = File.ReadAllLines(path).ToList();
list = list.OrderBy(x => Convert.ToInt32(x.Split('|')[0])).ToList();
for(var i = 0; i < list.Count; i++)
{
Console.WriteLine(list[i]);
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class TestClass {
public static void main(String[] args) {
List <LineItem> myList = new ArrayList<LineItem>();
myList.add(LineItem.getLineItem(500, 30));
myList.add(LineItem.getLineItem(300, 20));
myList.add(LineItem.getLineItem(900, 100));
System.out.println(myList);
Collections.sort(myList);
System.out.println("list after sort");
System.out.println(myList);
}
}
class LineItem implements Comparable<LineItem>{
int time;
int id ;
#Override
public String toString() {
return ""+ time + "|"+ id + " ";
}
#Override
public int compareTo(LineItem o) {
return this.time-o.time;
}
public static LineItem getLineItem( int time, int id ){
LineItem l = new LineItem();
l.time=time;
l.id=id;
return l;
}
}
I Have An Array,for example
string[] stArr= new string[5] { "1#3", "19#24", "10#12", "13#18", "20#21" };
i want to sort this array on
3-1=2;
24-19=5;
12-10=2;
18-13=5;
21-20=1;
and the sorting result should be like
string[] stArr= new string[5] { "20#21", "1#3", "10#12", "13#18", "20#21" };
I have to find the solution for all possible cases.
1>length of the array is not fixed(element in the array)
2>y always greater than x e.g x#y
3> i can not use list
You can use LINQ:
var sorted = stArr.OrderBy(s => s.Split('#')
.Select(n => Int32.Parse(n))
.Reverse()
.Aggregate((first,second) => first - second));
For Your Case:
stArr = stArr.OrderBy(s => s.Split('#')
.Select(n => Int32.Parse(n))
.Reverse()
.Aggregate((first,second) => first - second)).ToArray();
try this
string[] stArr = new string[5] { "1#3", "19#24", "10#12", "13#18", "20#21" };
Array.Sort(stArr, new Comparison<string>(compare));
int compare(string z, string t)
{
var xarr = z.Split('#');
var yarr = t.Split('#');
var x1 = int.Parse(xarr[0]);
var y1 = int.Parse(xarr[1]);
var x2 = int.Parse(yarr[0]);
var y2 = int.Parse(yarr[1]);
return (y1 - x1).CompareTo(y2 - x2);
}
Solving this problem is identical to solving any other sorting problem where the order is to be specified by your code - you have to write a custom comparison method, and pass it to the built-in sorter.
In your situation, it means writing something like this:
private static int FindDiff(string s) {
// Split the string at #
// Parse both sides as int
// return rightSide-leftSide
}
private static int CompareDiff(string a, string b) {
return FindDiff(a).CompareTo(FindDiff(b));
}
public static void Main() {
... // Prepare your array
string[] stArr = ...
Array.Sort(stArr, CompareDiff);
}
This approach uses Array.Sort overload with the Comparison<T> delegate implemented in the CompareDiff method. The heart of the solution is the FindDiff method, which takes a string, and produces a numeric value which must be used for comparison.
you can try the following ( using traditional way)
public class Program
{
public static void Main()
{
string[] strArr= new string[5] { "1#3", "19#24", "10#12", "13#18", "20#21" };
var list = new List<Item>();
foreach(var item in strArr){
list.Add(new Item(item));
}
strArr = list.OrderBy(t=>t.Sort).Select(t=>t.Value).ToArray();
foreach(var item in strArr)
Console.WriteLine(item);
}
}
public class Item
{
public Item(string str)
{
var split = str.Split('#');
A = Convert.ToInt32(split[0]);
B = Convert.ToInt32(split[1]);
}
public int A{get; set;}
public int B{get; set;}
public int Sort { get { return Math.Abs(B - A);}}
public string Value { get { return string.Format("{0}#{1}",B,A); }}
}
here a working demo
hope it will help you
Without LINQ and Lists :) Old School.
static void Sort(string [] strArray)
{
try
{
string[] order = new string[strArray.Length];
string[] sortedarray = new string[strArray.Length];
for (int i = 0; i < strArray.Length; i++)
{
string[] values = strArray[i].ToString().Split('#');
int index=int.Parse(values[1].ToString()) - int.Parse(values[0].ToString());
order[i] = strArray[i].ToString() + "," + index;
}
for (int i = 0; i < order.Length; i++)
{
string[] values2 = order[i].ToString().Split(',');
if (sortedarray[int.Parse(values2[1].ToString())-1] == null)
{
sortedarray[int.Parse(values2[1].ToString())-1] = values2[0].ToString();
}
else
{
if ((int.Parse(values2[1].ToString())) >= sortedarray.Length)
{
sortedarray[(int.Parse(values2[1].ToString())-1) - 1] = values2[0].ToString();
}
else if ((int.Parse(values2[1].ToString())) < sortedarray.Length)
{
sortedarray[(int.Parse(values2[1].ToString())-1) + 1] = values2[0].ToString();
}
}
}
for (int i = 0; i < sortedarray.Length; i++)
{
Console.WriteLine(sortedarray[i]);
}
Console.Read();
}
catch (Exception ex)
{
throw;
}
finally
{
}
there some method equal list() of php in C#?
usage list() in PHP:
$array = array('foo','baa');
list($foo, $baa) = $array;
echo $foo; //foo
echo $baa; //baa
equivalent in javascript:
var arr = ['foo','baa'];
var foo;
var baa;
[foo, baa] = arr;
Thanks in advance!
There is no direct language equivalent in C#. While collection initializers can be used to construct the array, there is no way to extract elements directly.
This requires explicitly setting variables, ie:
var theArray = GetArrayFromSomewhere();
var foo = theArray[0];
var bar = theArray[1];
This is more similar to the original intention, though some might not like all the ceremony :
string a = null, b = null, c = null;
new ValList(v => a = v,
v => b = v,
v => c = v).SetFrom(new string[] { "foo", "bar" });
//here a is "foo", b will be "bar", and c is still null
And the simple helper class:
class ValList
{
private Action<string>[] _setters;
public ValList(params Action<string>[] refs)
{
_setters = refs;
}
internal void SetFrom(string[] values)
{
for (int i = 0; i < values.Length && i < _setters.Length; i++)
_setters[i](values[i]);
}
}
One way to do the original php (I know nothing about PHP) task in C# would be
List<string> name_list = new List<string>{"transmogrify","untransmogrify"};
name_list.ForEach(x => Debug.WriteLine(x));
Which leads to the more general observation, that C# allows you to do a lot while leaving the variables in the array or list. LINQ in particular makes doing many things quite simple. So if you are looking for a way to replicate some PHP code in C# I would think in those terms. Just one parting example, if you had an array of ints you wanted to sum you could do this
int[] some_ints = {1, 2, 3, 4};
int sum += some_ints.Sum();
As Reed said ,
There is no direct language equivalent in C#.
But you can create it like below ↓
class Program
{
static void Main(string[] args)
{
string[] tmp = new string[] { "foo", "baa" };
string foo, baa;
tmp.Go(out foo, out baa);
Console.WriteLine(foo);
Console.WriteLine(baa);
Console.ReadKey();
}
}
public static class PHPList
{
public static void Go(this string[] soruce, out string p1, out string p2)
{
p1 = soruce[0] + "";
p2 = soruce[1] + "";
}
}
Just piggy-backing #Yoni's answer into an extension method. This was a cute and silly exercise; however, as has been pointed out in comments and answers, some language features simply do not port from one language to another.
In PHP, list($a, $b) = $c constitutes an assignment, and since no variable declarations are required (the list() is the declaration) it can provide terse and clean assignment syntax.
In C# however, since variable declarations are required prior to usage, you're better off simply assigning the value off the list at that time, as the following example will show.
Speaking of, incoming example:
public static void Into<TSource>(this IEnumerable<TSource> source,
params Action<TSource>[] actions)
{
if (ReferenceEquals(source, null)) {
throw new ArgumentNullException("source");
}
if (ReferenceEquals(actions, null)) {
throw new ArgumentNullException("actions");
}
foreach (var assignment in actions.Zip(source, (action, item) => new {
Action = action,
Item = item,
})) {
assignment.Action.Invoke(assignment.Item);
}
}
So you can simply collection.Into(o => a = o, o => ...); for example:
var numbers = new[] { 1, 2, 3, 4, 5 };
int a = 0, b = 0, c = 0, d = 0;
int e = 0, f = 0, g = 0, h = 0, i = 0, j = 0;
numbers.Into(o => a = o,
o => b = o,
o => c = o,
o => d = o);
numbers.Into(o => e = o,
o => f = o,
o => g = o,
o => h = o,
o => i = o,
o => j = o);
This will yield:
Console.WriteLine(a); // 1
Console.WriteLine(b); // 2
Console.WriteLine(c); // 3
Console.WriteLine(d); // 4
Console.WriteLine(e); // 1
Console.WriteLine(f); // 2
Console.WriteLine(g); // 3
Console.WriteLine(h); // 4
Console.WriteLine(i); // 5
Console.WriteLine(j); // 0
Perhaps some Expression<> magic can shorten it to:
numbers.Into(o => a,
o => b,
... )
I have a dictionary containg ID which are alphanumeric (e.g. a10a10 & d10a9) from which I want the biggest ID, meaning 9 < 10 < a ...
When I use the following code, d10a9 is MAX since 9 is sorted before 10
var lsd = new Dictionary<string, string>();
lsd.Add("a", "d10a10");
lsd.Add("b", "d10a9");
string max = lsd.Max(kvp => kvp.Value);
How can I get the Max value of the IDs with the Longest string combined?
I think you may try to roll your own IComparer<string>
class HumanSortComparer : IComparer<string>
{
public int Compare(string x, string y)
{
// your human sorting logic here
}
}
Usage:
var last = collection.OrderBy(x => x.Value, new HumanSortComparer()).LastOrDefault();
if (last != null)
string max = last.Value;
this works like a charm assuming IDs always start with "d10a":
int max = lsd.Max(kvp => Convert.ToInt32(kvp.Value.Substring(4)));
Console.Write(string.Format("d10a{0}", max));
One way would be to do this
string max =lsd.Where(kvp=>kvp.Value.Length==lsd.Max(k=>k.Value.Length)).Max(kvp => kvp.Value);
however I think that this method would evalute the max length for each item so you may be better to extract it to a variable first
int maxLength=lsd.Max(kvp=>kvp.Value.Length);
string max = lsd.Where(kvp=>kvp.Value.Length == maxLength).Max(kvp => kvp.Value);
If you are going to have null strings in there you may need to perform null checks too
int maxLength=lsd.Max(kvp=>(kvp.Value??String.Empty).Length);
string max = lsd.Where(kvp=>(kvp.Value??String.Empty).Length == maxLength).Max(kvp => kvp.Value);
Alternatively treat your string as Base36 number and convert to long for the max function and then convert back again to get the max string.
string max =lsd.Max(tvp=>tvp.Value.FromBase36()).ToBase36();
public static class Base36 {
public static long FromBase36(this string src) {
return src.ToLower().Select(x=>(int)x<58 ? x-48 : x-87).Aggregate(0L,(s,x)=>s*36+x);
}
public static string ToBase36(this long src) {
StringBuilder result=new StringBuilder();
while(src>0) {
var digit=(int)(src % 36);
digit=(digit<10) ? digit+48 :digit+87;
result.Insert(0,(char)digit);
src=src / 36;
}
return result.ToString();
}
}
Finally just just the Agregate extension method instead of Max as this lets you do all the comparison logic....
lsd.Agregate(string.Empty,(a,b)=> a.Length == b.Length ? (a>b ? a:b) : (a.Length>b.Length ? a:b));
This could doesn't have null checks but you easily add them in.
I think if you did this:
var max = lsd.OrderByDescending(x => x.Value)
.GroupBy(x => x.Value.Length)
.OrderByDescending(x => x.Key)
.SelectMany(x => x)
.FirstOrDefault();
It may give you what you want.
You need StringComparer.OrdinalIgnoreCase.
Without the need to use linq, the function that do that is quite simple.
Complexity is, of course, O(n).
public static KeyValuePair<string, string> FindMax(IEnumerable<KeyValuePair<string, string>> lsd)
{
var comparer = StringComparer.OrdinalIgnoreCase;
var best = default(KeyValuePair<string, string>);
bool isFirst = true;
foreach (KeyValuePair<string, string> kvp in lsd)
{
if (isFirst || comparer.Compare(kvp.Value, best.Value) > 0)
{
isFirst = false;
best = kvp;
}
}
return best;
}
Okay - I think you need to first turn each key into a series of strings and numbers - since you need the whole number to be able to determine the comparison. Then you implement an IComparer - I've tested this with your two input strings as well as with a few others and it appears to do what you want. The performance could possibly be improved - but I was brainstorming it!
Create this class:
public class ValueChain
{
public readonly IEnumerable<object> Values;
public int ValueCount = 0;
private static readonly Regex _rx =
new Regex("((?<alpha>[a-z]+)|(?<numeric>([0-9]+)))",
RegexOptions.Compiled | RegexOptions.IgnoreCase);
public ValueChain(string valueString)
{
Values = Parse(valueString);
}
private IEnumerable<object> Parse(string valueString)
{
var matches = _rx.Matches(valueString);
ValueCount = matches.Count;
foreach (var match in matches.Cast<Match>())
{
if (match.Groups["alpha"].Success)
yield return match.Groups["alpha"].Value;
else if (match.Groups["numeric"].Success)
yield return int.Parse(match.Groups["numeric"].Value);
}
}
}
Now this comparer:
public class ValueChainComparer : IComparer<ValueChain>
{
private IComparer<string> StringComparer;
public ValueChainComparer()
: this(global::System.StringComparer.OrdinalIgnoreCase)
{
}
public ValueChainComparer(IComparer<string> stringComparer)
{
StringComparer = stringComparer;
}
#region IComparer<ValueChain> Members
public int Compare(ValueChain x, ValueChain y)
{
//todo: null checks
int comparison = 0;
foreach (var pair in x.Values.Zip
(y.Values, (xVal, yVal) => new { XVal = xVal, YVal = yVal }))
{
//types match?
if (pair.XVal.GetType().Equals(pair.YVal.GetType()))
{
if (pair.XVal is string)
comparison = StringComparer.Compare(
(string)pair.XVal, (string)pair.YVal);
else if (pair.XVal is int) //unboxing here - could be changed
comparison = Comparer<int>.Default.Compare(
(int)pair.XVal, (int)pair.YVal);
if (comparison != 0)
return comparison;
}
else //according to your rules strings are always greater than numbers.
{
if (pair.XVal is string)
return 1;
else
return -1;
}
}
if (comparison == 0) //ah yes, but were they the same length?
{
//whichever one has the most values is greater
return x.ValueCount == y.ValueCount ?
0 : x.ValueCount < y.ValueCount ? -1 : 1;
}
return comparison;
}
#endregion
}
Now you can get the max using OrderByDescending on an IEnumerable<ValueChain> and FirstOrDefault:
[TestMethod]
public void TestMethod1()
{
List<ValueChain> values = new List<ValueChain>(new []
{
new ValueChain("d10a9"),
new ValueChain("d10a10")
});
ValueChain max =
values.OrderByDescending(v => v, new ValueChainComparer()).FirstOrDefault();
}
So you can use this to sort the string values in your dictionary:
var maxKvp = lsd.OrderByDescending(kvp => new ValueChain(kvp.Value),
new ValueChainComparer()).FirstOrDefault();