IComparer用于整数并强制空字符串结束

时间:2010-04-06 13:21:43

标签: c#

我写过以下IComparer,但我需要一些帮助。我正在尝试对数字列表进行排序,但有些数字可能尚未填写。我希望这些数字始终发送到列表的末尾...例如......

[EMPTY],1,[EMPTY],3,2

会变成......

1,2,3,[EMPTY],[EMPTY]

并且反过来会变成......

3,2,1,[EMPTY],[EMPTY]

有什么想法吗?

        public int Compare(ListViewItem x, ListViewItem y)
    {
        int comparison = int.MinValue;
        ListViewItem.ListViewSubItem itemOne = x.SubItems[subItemIndex];
        ListViewItem.ListViewSubItem itemTwo = y.SubItems[subItemIndex];

        if (!string.IsNullOrEmpty(itemOne.Text) && !string.IsNullOrEmpty(itemTwo.Text))
        {
            uint itemOneComparison = uint.Parse(itemOne.Text);
            uint itemTwoComparison = uint.Parse(itemTwo.Text);

            comparison = itemOneComparison.CompareTo(itemTwoComparison);
        }
        else
        {
            // ALWAYS SEND TO BOTTOM/END OF LIST.
        }

        // Calculate correct return value based on object comparison.
        if (OrderOfSort == SortOrder.Descending)
        {
            // Descending sort is selected, return negative result of compare operation.
            comparison = (-comparison);
        }
        else if (OrderOfSort == SortOrder.None)
        {
            // Return '0' to indicate they are equal.
            comparison = 0;
        }

        return comparison;
    }

干杯。

5 个答案:

答案 0 :(得分:4)

您的逻辑略有偏差:如果 中的为空,则会输入else,但您只希望空的那个转到列表的末尾,而不是非空的。这样的事情应该有效:

public int Compare(ListViewItem x, ListViewItem y)
{
    ListViewItem.ListViewSubItem itemOne = x.SubItems[subItemIndex];
    ListViewItem.ListViewSubItem itemTwo = y.SubItems[subItemIndex];

    // if they're both empty, return 0
    if (string.IsNullOrEmpty(itemOne.Text) && string.IsNullOrEmpty(itemTwo.Text))
        return 0;

    // if itemOne is empty, it comes second
    if (string.IsNullOrEmpty(itemOne.Text))
        return 1;

    // if itemTwo is empty, it comes second
    if (string.IsNullOrEmpty(itemTwo.Text)
        return -1;

    uint itemOneComparison = uint.Parse(itemOne.Text);
    uint itemTwoComparison = uint.Parse(itemTwo.Text);

    // Calculate correct return value based on object comparison.
    int comparison = itemOneComparison.CompareTo(itemTwoComparison);
    if (OrderOfSort == SortOrder.Descending)
        comparison = (-comparison);

    return comparison;
}

(我可能已经得到了“1”和“-1”,因为当他们空着回到前面时,我永远不会记得:)

答案 1 :(得分:2)

我实际上是以完全不同的方式处理它,删除空插槽,对列表进行排序,然后将空的添加到列表的末尾

static void Main(string[] args)
{
    List<string> ints = new List<string> { "3", "1", "", "5", "", "2" };
    CustomIntSort(ints, (x, y) => int.Parse(x) - int.Parse(y)); // Ascending
    ints.ForEach(i => Console.WriteLine("[{0}]", i));

    CustomIntSort(ints, (x, y) => int.Parse(y) - int.Parse(x)); // Descending
    ints.ForEach(i => Console.WriteLine("[{0}]", i)); 
}
private static void CustomIntSort(List<string> ints, Comparison<string> Comparer)
{
    int emptySlots = CountAndRemove(ints);
    ints.Sort(Comparer);
    for (int i = 0; i < emptySlots; i++)
        ints.Add("");
}
private static int CountAndRemove(List<string> ints)
{
    int emptySlots = 0;
    int i = 0;

    while (i < ints.Count)
    {
        if (string.IsNullOrEmpty(ints[i]))
        {
            emptySlots++;
            ints.RemoveAt(i);
        }
        else
            i++;
    }
    return emptySlots;
}

这个问题最近引起了我的注意,这个比较器也会这样做

class CustomComparer
    : IComparer<string>
{
    private bool isAscending;
    public CustomComparer(bool isAscending = true)
    {
        this.isAscending = isAscending;
    }
    public int Compare(string x, string y)
    {
        long ix = CustomParser(x) * (isAscending ? 1 : -1);
        long iy = CustomParser(y) * (isAscending ? 1 : -1);
        return ix.CompareTo(iy) ;
    }
    private long CustomParser(string s)
    {
        if (string.IsNullOrEmpty(s))
            return isAscending ? int.MaxValue : int.MinValue;
        else
            return int.Parse(s);
    }
}

答案 2 :(得分:0)

始终为empty x值返回1,为empty y值返回-1。这意味着比较器在所有情况下都将空值视为更大的值,因此它们最终应该在排序列表的末尾。

当然,如果两者都是空的,你应该返回0,因为它们是相等的。

答案 3 :(得分:0)

你的//总是发送到底部/列表的末尾。当x或y参数为空时执行分支,即如果将非空值与空值进行比较,则将根据该规则对非空值进行排序。你可能想要更像这样的东西:

if (!string.IsNullOrEmpty(itemOne.Text) && !string.IsNullOrEmpty(itemTwo.Text))
{
    uint itemOneComparison = uint.Parse(itemOne.Text);
    uint itemTwoComparison = uint.Parse(itemTwo.Text);

    comparison = itemOneComparison.CompareTo(itemTwoComparison);
}
else if (!string.IsNullOrEmpty(itemOne.Text)
{
    comparison = -1;
}
else
{
    comparison = 1;
}

答案 4 :(得分:0)

else 
{ 
    //ALWAYS SEND TO BOTTOM/END OF LIST. 
    if (string.IsNullOrEmpty(itemOne.Text) && string.IsNullOrEmpty(itemTwo.Text)) 
    {
        return 0;
    }
    else if (string.IsNullOrEmpty(itemOne.Text)) 
    {
        return -1;
    }
    else if (string.IsNullOrEmpty(itemTwo.Text)) 
    {
        return 1;
    }
}