实际上,问题的另一个标题是:如何找到当前文化中字母值最高的字符?
看看以下代码:
static void Main(string[] args)
{
var input = new[] { "cote", "côte", "coté", "", "côté" };
var maxString = new string(new[] { char.MaxValue });
var byEnUsCulture = input.OrderBy(i =>
(String.IsNullOrEmpty(i)) ? maxString : i,
StringComparer.Create(new CultureInfo("en-US"), false)).ToList();
var byFrFrCulture = input.OrderBy(i =>
(String.IsNullOrEmpty(i)) ? maxString : i,
StringComparer.Create(new CultureInfo("fr-FR"), false)).ToList();
var byOrdinal = input.OrderBy(i =>
(String.IsNullOrEmpty(i)) ? maxString : i,
StringComparer.Ordinal).ToList();
foreach (var words in new[] { byEnUsCulture, byFrFrCulture, byOrdinal })
{
foreach (var word in words)
{
Console.Write("{0} ", (string.IsNullOrEmpty(word)) ? "xxxx" : word);
}
Console.WriteLine();
}
}
以上的输出是:
xxxx cote coté côte côté
xxxx cote côte coté côté
cote coté côte côté xxxx
但我想要的是:
cote côte coté côté xxxx
是否可以通过fr-FR
文化信息对上述单词进行排序,并仍然在集合末尾输出空(在输出中替换为xxxx
),所有这些只是通过使用OrderBy
?
注意:Here是预期订单的参考。
答案 0 :(得分:4)
我想您可以创建自己的StringComparer子类,始终确保在推迟到fr-FR比较器之前对空字符串进行最后排序。
答案 1 :(得分:0)
实现包装另一个字符串比较器的自定义字符串比较器。您的自定义比较器应始终将空字符串值设置为非空字符串,并将比较转发到包装的比较器实例仅,如果两个字符串都为非空。您实际上是将默认的comparer null行为应用于空字符串,但现在您正在反转结果。
代码示例:
class EmptyToEndComparer: StringComparer
{
public StringComparer InnerComparer { get; private set; }
public EmptyToEndComparer(StringComparer innerComparer)
{
if (innerComparer == null) throw new ArgumentNullException("innerComparer");
InnerComparer = innerComparer;
}
public override int Compare(string x, string y)
{
//Invert the standard behavior on null or empty
//http://msdn.microsoft.com/en-us/library/x1ea0esc%28v=vs.110%29.aspx
if (string.IsNullOrEmpty(x) && !string.IsNullOrEmpty(y))
return 1;
else if (!string.IsNullOrEmpty(x) && string.IsNullOrEmpty(y))
return -1;
else
return InnerComparer.Compare(x, y);
}
public override bool Equals(string x, string y)
{
return x == y;
}
public override int GetHashCode(string obj)
{
return obj.GetHashCode();
}
}
使用这样的类:
var byEnUsCulture = input.OrderBy(i => i, new EmptyToEndComparer(StringComparer.Create(new CultureInfo("en-US"), false))).ToList();
var byFrFrCulture = input.OrderBy(i => i, new EmptyToEndComparer(StringComparer.Create(new CultureInfo("fr-FR"), false))).ToList();
var byOrdinal = input.OrderBy(i => i, new EmptyToEndComparer(StringComparer.Ordinal)).ToList();
我的测试结果:
cote coté côte côté xxxx
cote côte coté côté xxxx
cote coté côte côté xxxx