Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
850 views
in Technique[技术] by (71.8m points)

c# - Fastest way to get list in custom order

I need to find the fastest way to get a small list of strings or chars in custom order. I found a lot of questions about sorting a list, but there is no question on the board or web about sorting a small list with a native type, all I found was way more complex.

For me it does not matter if my input list is a string list or char list. My list has 5 - 7 items, they look like this: "1","Q","A","8","9". I want to get my input ordered like this: "2", "3", "4", "5", "6", "7", "8", "9", "1", "J", "Q", "K", "A".

I tried the following codes:

1 = 3.1-3.5 milliseconds :

static readonly List<String> codeValueSortOrder = new List<String> 
{ 
    "2", "3", "4", "5", "6", "7", "8", "9", "1", "J", "Q", "K", "A" 
};
input.OrderBy(i => codeValueSortOrder.IndexOf(i.ToString())).ToList();

2 = 5.0-6.0 milliseconds:

input.OrderBy(i => i[1] == 'A')
     .ThenBy(i => i[1] == 'K')
     .ThenBy(i => i[1] == 'Q')
     .ThenBy(i => i[1] == 'J')
     .ThenBy(i => i.Substring(1, i.Length - 1) == "10")
     .ThenBy(i => i[1] == '9')
     .ThenBy(i => i[1] == '8')
     .ThenBy(i => i[1] == '7')
     .ThenBy(i => i[1] == '6')
     .ThenBy(i => i[1] == '5')
     .ThenBy(i => i[1] == '4')
     .ThenBy(i => i[1] == '3')
     .ThenBy(i => i[1] == '2')
     .ToList();

I also looked at a few projects at codeproject, but this codes are for million of items, I can′t imagine that they are the most efficient way if we just want to sort between 5 and 7 items. My goal is to perform the sorting in under 0.1 milliseonds, I have no idea if it is possible to accomplish that goal :)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You could use a Dictionary<string, int> where the key is the string and the value is the index.

You can even still use the List<string> as basis:

private static readonly List<string> _List = new List<string> { "2", "3", "4", "5", "6", "7", "8", "9", "1", "J", "Q", "K", "A" };
static readonly Dictionary<string, int> Order = _List
    .ToDictionary(str => str, str => _List.IndexOf(str) + 1);

Now you're able to use List.Sort which does not need to create a new list as the LINQ approaches:

var input = new List<string> { "1", "Q", "A", "8", "9" };
int i1, i2;
input.Sort((s1, s2) =>
{
    Order.TryGetValue(s1, out i1);
    Order.TryGetValue(s2, out i2);
    return i1.CompareTo(i2);
});

Result order: 8,9,1,Q,A

A quick test revealed: StopWatch.Elapsed.TotalMilliseconds 0.0045

Dictionary.TryGetValue returns either the index if the string was found or 0 otherwise. That's why i've used _List.IndexOf(str) + 1 above to force that found items come last.

If you want a descending order you just have to reverse it:

return i2.CompareTo(i1);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...