C#max()没有返回自然的最高值

时间:2017-02-15 12:50:46

标签: c#

我有一个<string, Point>字典,这个字典中的键看起来像这样:

  • char_1_1
  • char_1_2
  • ...
  • char_1_9
  • char_1_10

现在我使用以下语句来接收键的最高值:

pointsWhichBelongTogether.Keys.Where(key => key.Contains(searchStringPattern[0] + "_" + searchStringPattern[1] + "_")).OrderBy(x => x, new NaturalStringComparer()).Max()

使用以下比较类:

public class NaturalStringComparer : IComparer<string>
    {
        private static readonly Regex _re = new Regex(@"(?<=\D)(?=\d)|(?<=\d)(?=\D)", RegexOptions.Compiled);

        public int Compare(string x, string y)
        {
            x = x.ToLower();
            y = y.ToLower();
            if (string.Compare(x, 0, y, 0, Math.Min(x.Length, y.Length)) == 0)
            {
                if (x.Length == y.Length) return 0;
                return x.Length < y.Length ? -1 : 1;
            }
            var a = _re.Split(x);
            var b = _re.Split(y);
            int i = 0;
            while (true)
            {
                int r = PartCompare(a[i], b[i]);
                if (r != 0) return r;
                ++i;
            }
        }

        private static int PartCompare(string x, string y)
        {
            int a, b;
            if (int.TryParse(x, out a) && int.TryParse(y, out b))
                return a.CompareTo(b);
            return x.CompareTo(y);
        }
    }

所以我假设List是自然排序的,Max-Functions只是获得最高值。但max()返回char_1_9作为最高值。这个max() - 是否重新排序?

2 个答案:

答案 0 :(得分:5)

您有两种选择:

  • 从排序列表中取Last
  • 订单降序并采取第一个

现在您使用比较器排序,但Max不使用比较器,而是使用默认比较器来查找最大值。

pointsWhichBelongTogether.Keys.Where(key => key.Contains(searchStringPattern[0] + "_" + searchStringPattern[1] + "_"))
    .OrderBy(x => x, new NaturalStringComparer()).Last();

pointsWhichBelongTogether.Keys.Where(key => key.Contains(searchStringPattern[0] + "_" + searchStringPattern[1] + "_"))
    .OrderByDescending(x => x, new NaturalStringComparer()).First();

编辑:在之前的版本中我建议将比较器传递给Max,但似乎没有重载需要比较器,只有选择器。

答案 1 :(得分:1)

string类型已经实现了IComparable<string>,因此Max()使用此实现,无论之前的排序如何。我会命令你的值下降并取第一个值:

var max = pointsWhichBelongTogether.Keys
    .Where(key => key.Contains(searchStringPattern[0] + "_" + searchStringPattern[1] + "_"))
    .OrderByDescending(x => x, new NaturalStringComparer())
    .FirstOrDefault();