.NET IComparable:如何实现

时间:2011-08-12 10:33:48

标签: c# .net

我有一个对象列表,我需要按照其格式

的顺序对它们进行排序
x~x~x~x~x~x~x~x

e.g。

"something~XXX~XXX~XXX~XXX~XXX~OTHER~XXX"  
"something~XsdXX~XXX~XfdXX~XXX~XXX~OTHER~XXX"  
"Detail~XXX~~XdfXX~XXX~XXX~OTHER~XXX"  
"x~x~~~~~x~x"

我需要通过获取每个tilda和排序之间的每个字符串进行排序。所以首先我想把字符串带到第一个tilda并按该字符串排序。然后我想转到第一个和第二个tilda之间的第二个字符串,然后按该字符串排序。我想继续前进,直到没有更多的字符串可以排序。 这是我的尝试。你能告诉我我做错了什么:

    public int CompareTo(object obj)
    {
        if (!(obj is Detail))
            return -1;

        Detail detailToCompare = obj as Detail;
        string[] splitString1 = detailToCompare.ID.Split('~');
        string[] splitString2 = ID.Split('~');

        for (int i = 0; i < splitString1.Length; i++)
        {
            //What should I do here????
            //return String.Compare(splitString1[i], splitString2[i]);
        }

        return 0;
    }

2 个答案:

答案 0 :(得分:2)

这实际上取决于如何您希望这些ID排序。也许你的意思是这个?:

…
for (int i = 0; i < splitString1.Length; i++)
{
    int partComparisonResult = String.Compare(splitString1[i], splitString2[i]);
    if (partComparisonResult == 0)
    {              // these two parts are identical,
        continue;  // so move on to the next position.
    }              // (this clause is superfluous, but included for clarity.)
    else
    {              // these parts differ, so return their sort order:
        return partComparisonResult;
    }
}

哪个应该导致如下命令:

//      A~A~C~D~E~F~G~H
//        |
//      A~B~C~C~E~F~G~H
//            |
//      A~B~C~D~E~F~G~H
//            |
//      A~B~C~E~E~F~G~H
//          |
//      A~B~D~D~E~F~G~H

也就是说,只要它们相等,就继续比较一个部分。一旦找到不同的部分,返回该部分的比较结果作为整个ID的比较结果。

顺便说一下,您还应该检查两个ID是否包含正确数量的部分:

if (splitString1.Length != 8)
{
    throw new ArgumentException(…);
}
if (splitString2.Length != 8)
{
    throw new ArgumentException(…);
}

答案 1 :(得分:0)

如果您只需要对列表进行排序,也可以在LINQ中完成:

var q = details.OrderBy(a=>0); // to get an initial IOrderedEnumerable
for (int i = 0; i < details[0].Split('~').Length; i++)
{
    var itemp = i; // create local copy of i for closure
    q = q.ThenBy(d => d.Split('~')[itemp].ToUpperInvariant());
}

如果details是IEnumerable,则q是包含已排序详细信息的集合。对于样本ID,q将按顺序包含:

Detail~XXX~~XdfXX~XXX~XXX~OTHER~XXX
something~XsdXX~XXX~XfdXX~XXX~XXX~OTHER~XXX
something~XXX~XXX~XXX~XXX~XXX~OTHER~XXX
x~x~~~~~x~x

(编辑纠正代码中的初始错误)

编辑:

如果你想使用IComparable,你也可以这样做:

public int CompareTo(object obj)
{
    if (!(obj is Detail))
         throw new ArgumentException("obj");

    Detail detailToCompare = obj as Detail;

    // get first unique element, and compare that        
    var firstnonequal = this.ID.Split('~')
         .Zip(detailToCompare.ID.Split('~'),
              (a, b) => new { ThisPartValue = a, OtherPartValue = b })
         .FirstOrDefault(a => a.ThisPartValue != a.OtherPartValue);
         if (firstnonequal == null) return 0; // both IDs are equal
         return firstnonequal.ThisPartValue.CompareTo(firstnonequal.OtherPartValue);
         // ^ include flag for case insentivity, if desired
  }