代码之家  ›  专栏  ›  技术社区  ›  steve

多值比较器

  •  4
  • steve  · 技术社区  · 15 年前

    是否可以使用iComparer在对象中使用两个值对列表进行排序?

    我有一个自定义比较器类,它根据value1进行排序。但是,对value1和value2进行排序的最佳方法是什么?

    3 回复  |  直到 15 年前
        1
  •  13
  •   mqp    15 年前

    你的 IComparer 类应该处理它。例如:

    public class ThingComparer : IComparer
    {
        public int Compare(object x, object y)
        {
            // null- and type-checking omitted for clarity
    
            // sort by A, B, and then C
    
            if (x.A != y.A) return x.A.CompareTo(y.A);
            if (x.B != y.B) return x.B.CompareTo(y.B);
            return x.C.CompareTo(y.C);
        }
    }
    
        2
  •  0
  •   Fredrik Mörk    15 年前

    如果实现自己的比较器,则可以执行任何排序:

    List<Customer> customers = GetCustomers();
    customers.Sort(delegate(Customer x, Customer y)
    {
        if (x.Name != y.Name)
        {
            return x.Name.CompareTo(y.Name);
        }
    
        return x.Location.CompareTo(y.Location);
    });
    

    现在,上面的代码不是IComparer类,但是比较方法是相同的。

        3
  •  0
  •   Matt Hinze    15 年前
    public class ScratchComparer : IComparer<Scratch>
    {
        public int Compare(Scratch x, Scratch y)
        {
            return x.Foo.CompareTo(y.Foo).CompareTo(0.CompareTo(x.Bar.CompareTo(y.Bar)));
        }
    }
    
    [TestFixture]
    public class Scratch
    {
        public virtual int Foo { get; set; }
        public virtual int Bar { get; set; }
    
        [Test]
        public void Should_sort()
        {
            var scratches = new[]
            {
                new Scratch {Foo = 1, Bar = 1},
                new Scratch {Foo = 2, Bar = 1},
                new Scratch {Foo = 1, Bar = 1},
                new Scratch {Foo = 1, Bar = 2}
            };
    
            // IComparer
            Array.Sort(scratches, new ScratchComparer());
    
            scratches[0].Foo.ShouldEqual(1);
            scratches[0].Bar.ShouldEqual(1);
    
            scratches[1].Foo.ShouldEqual(1);
            scratches[1].Bar.ShouldEqual(1);
    
            scratches[2].Foo.ShouldEqual(1);
            scratches[2].Bar.ShouldEqual(2);
    
            scratches[3].Foo.ShouldEqual(2);
            scratches[3].Bar.ShouldEqual(1);
    
            // better
            Scratch[] ordered = scratches.OrderBy(x => x.Foo).ThenBy(x => x.Bar).ToArray();
    
            ordered[0].Foo.ShouldEqual(1);
            ordered[0].Bar.ShouldEqual(1);
    
            ordered[1].Foo.ShouldEqual(1);
            ordered[1].Bar.ShouldEqual(1);
    
            ordered[2].Foo.ShouldEqual(1);
            ordered[2].Bar.ShouldEqual(2);
    
            ordered[3].Foo.ShouldEqual(2);
            ordered[3].Bar.ShouldEqual(1);
        }
    }