订购法国字符串的集合,并在最后留下空条目

时间:2013-11-18 10:37:18

标签: c# string linq cultureinfo

实际上,问题的另一个标题是:如何找到当前文化中字母值最高的字符

看看以下代码:

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是预期订单的参考。

2 个答案:

答案 0 :(得分:4)

我想您可以创建自己的StringComparer子类,始终确保在推迟到fr-FR比较器之前对空字符串进行最后排序。

答案 1 :(得分:0)

实现包装另一个字符串比较器的自定义字符串比较器。您的自定义比较器应始终将空字符串值设置为非空字符串,并将比较转发到包装的比较器实例,如果两个字符串都为非空。您实际上是将默认的comparer null行为应用于空字符串,但现在您正在反转结果。

  • 几乎没有任何代码
  • 适用于任何字符串比较器
  • Guarentees你的空字符串 排序到最后
  • 保持单一排序操作(非常确定 .net使用QSort)

代码示例:

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