我有一个字符串列表,如: -
" 008"," a"," 007"," b"," c",&# 34; 009"
需要OutPut: -
" a"," b"," c"," 007"," 008",&# 34; 009" 到目前为止我尝试了什么
string[] things= new string[] { "aaul", "bob", "lauren", "007", "008", "009"};
foreach (var thing in things.AsQueryable().OrderByDescending(x => x, new SemiNumericComparer()))
{
Console.WriteLine(thing);
}
public class SemiNumericComparer: IComparer<string>
{
public int Compare(string s1, string s2)
{
if (IsNumeric(s1) && IsNumeric(s2))
{
if (Convert.ToInt32(s1) > Convert.ToInt32(s2)) return 0;
if (Convert.ToInt32(s1) < Convert.ToInt32(s2)) return 1;
if (Convert.ToInt32(s1) == Convert.ToInt32(s2)) return -1;
}
if (IsNumeric(s1) && !IsNumeric(s2)){
return -1;
}
if (!IsNumeric(s1) && IsNumeric(s2)){
return 1;
};
return string.Compare(s1, s2, true);
}
public static bool IsNumeric(object value)
{
try {
int i = Convert.ToInt32(value.ToString());
return true;
}
catch (FormatException) {
return false;
}
}
}
Here is problem fiddle using above solution
我能够获得像
这样的输出a,b,c,009,008,007或007,008,009,c,b,a但需要a,b,c,007,008,009任何想法?
答案 0 :(得分:4)
你想订购两个组,首先是那些不是整数然后是整数的组。第一组按字典顺序排序,而数字按其值排序?
我使用下面的扩展方法try-parses string to int:
public static int? TryGetInt(this string item)
{
int i;
bool success = int.TryParse(item, out i);
return success ? (int?)i : (int?)null;
}
然后您可以使用此LINQ查询来获得所需的顺序:
string[] things = new string[] { "008", "bob", "009", "007", "aaul", "lauren" };
var ordered = things
.Select(s => new { s, numberOrNull = s.TryGetInt() }) // store in anonymous type
.OrderBy(x => x.numberOrNull.HasValue ? 1 : 0) // first non-integer group
.ThenBy(x => x.numberOrNull.HasValue ? x.numberOrNull.Value : int.MinValue) // then by number value
.ThenBy(x => x.s) // if they weren't numbers order lexicographically
.Select(x => x.s); // select the string
答案 1 :(得分:2)
首先将不同的起始字母组(数字或非数字)分开,然后对每个组进行排序
things.OrderBy(x => char.IsDigit(x.FirstOrDefault())).ThenBy(x => x)
答案 2 :(得分:2)
public class SemiNumericComparer: IComparer<string>
{
public int Compare(string s1, string s2)
{
if (IsNumeric(s1) && IsNumeric(s2))
{
if (Convert.ToInt32(s1) > Convert.ToInt32(s2)) return 1;
if (Convert.ToInt32(s1) < Convert.ToInt32(s2)) return -1;
if (Convert.ToInt32(s1) == Convert.ToInt32(s2)) return 0;
}
if (IsNumeric(s1) && !IsNumeric(s2))
return 1;
if (!IsNumeric(s1) && IsNumeric(s2))
return -1;
return string.Compare(s1, s2, true);
}
public static bool IsNumeric(object value)
{
try {
int i = Convert.ToInt32(value.ToString());
return true;
}
catch (FormatException) {
return false;
}
}
}
取自here并将其修改为先排序字母
使用OrderBy
代替OrderByDescending
答案 3 :(得分:2)
首先按int / not int排序,然后按内容
排序string[] things = new string[] { "a", "b", "c", "009", "008", "007" };
int temp=0;
string[] result = things.OrderBy(x => int.TryParse(x, out temp))
.ThenBy(x => x)
.ToArray();
更新到蒂姆的评论(natural order
int
值和lexicographical
strings
string[] things = new string[] { "c", "b", "a", "009", "008", "007" , "1234", "299" };
int temp = 0;
string[] result = things.OrderBy(x => int.TryParse(x, out temp) ? temp : int.MinValue)
.ThenBy(x => x)
.ToArray();
答案 4 :(得分:2)
使用Regex尝试以下内容:
string[] str = { "008", "abhi", "007", "bcd", "cde", "009" };
str = str.OrderBy(x => Regex.IsMatch(x, @"^\d+$")).ThenBy(x => x).ToArray<string>();
答案 5 :(得分:2)
你做错了是Compare
方法的实施。
仔细查看文档:
返回值
有符号整数,表示x和y的相对值,如下表所示。
Value Meaning
Less than zero x is less than y.
Zero x equals y.
Greater than zero x is greater than y.
你正在返回它应该在&#34中的反向;两个字符串都是数字&#34;案件。只需切换它就可以了:
if (Convert.ToInt32(s1) > Convert.ToInt32(s2)) return 1;
if (Convert.ToInt32(s1) < Convert.ToInt32(s2)) return -1;
if (Convert.ToInt32(s1) == Convert.ToInt32(s2)) return 0;
答案 6 :(得分:1)
试试这个:
public class SemiNumericComparer : IComparer<string>
{
public int Compare(string s1, string s2)
{
int i1, i2;
bool b1 = int.TryParse(s1, out i1);
bool b2 = int.TryParse(s2, out i2);
if (b1 && b2)
{
return i1.CompareTo(i2);
}
if (b1) return 1;
if (b2) return -1;
return string.Compare(s1, s2, true);
}
}