.net List的并集和交集

关于List的交集和并集的东西,上代码

  class Program
    {
        static void Main(string[] args)
        {
            List<Fish> a = new List<Fish>();
            a.Add(new Fish() {Name="测试1",ID=0,Message="" });
            a.Add(new Fish() { Name = "测试2", ID = 1, Message = "" });
            a.Add(new Fish() { Name = "测试3", ID = 2, Message = "" });
            a.Add(new Fish() { Name = "测试4", ID = 3, Message = "" });
            List<Fish> b = new List<Fish>();
            b.Add(new Fish() { Name = "测试1", ID = 0, Message = "" });
            b.Add(new Fish() { Name = "测试3", ID = 5, Message = "" });
            b.Add(new Fish() { Name = "测试5", ID = 6, Message = "" });


            List<Fish> c = a.Union(b).ToList();
  //List<Fish> c = a.Intersect(b).ToList();
foreach (var item in c) { Console.WriteLine("Name:{0},ID:{1}", item.Name, item.ID); } Console.ReadLine(); } } public class Fish { public string Name { get; set; } public int ID { get; set; } public string Message { get; set; } }

一个简单的测试类有三个属性,现在我想取a和b的并集,结果如下:

结果并不是我想要的,“测试1”这个结果应该显示一次就够了,而 List<Fish> c = a.Intersect(b).ToList();显示的结果更是空白,这是怎么回事儿?
来看一下Union的原型

        //
        // 摘要:
        //     通过使用默认的相等比较器生成两个序列的并集。
        //
        // 参数:
        //   first:
        //     一个 System.Collections.Generic.IEnumerable<T>,它的非重复元素构成联合的第一个集。
        //
        //   second:
        //     一个 System.Collections.Generic.IEnumerable<T>,它的非重复元素构成联合的第二个集。
        //
        // 类型参数:
        //   TSource:
        //     输入序列中的元素的类型。
        //
        // 返回结果:
        //     一个 System.Collections.Generic.IEnumerable<T>,包含两个输入序列中的元素(重复元素除外)。
        //
        // 异常:
        //   System.ArgumentNullException:
        //     first 或 second 为 null。
        public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second);
        //
        // 摘要:
        //     通过使用指定的 System.Collections.Generic.IEqualityComparer<T> 生成两个序列的并集。
        //
        // 参数:
        //   first:
        //     一个 System.Collections.Generic.IEnumerable<T>,它的非重复元素构成联合的第一个集。
        //
        //   second:
        //     一个 System.Collections.Generic.IEnumerable<T>,它的非重复元素构成联合的第二个集。
        //
        //   comparer:
        //     用于对值进行比较的 System.Collections.Generic.IEqualityComparer<T>。
        //
        // 类型参数:
        //   TSource:
        //     输入序列中的元素的类型。
        //
        // 返回结果:
        //     一个 System.Collections.Generic.IEnumerable<T>,包含两个输入序列中的元素(重复元素除外)。
        //
        // 异常:
        //   System.ArgumentNullException:
        //     first 或 second 为 null。
        public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer);

还有一个重载函数,还有一个比较器
那咱们就写一个比较器呗

    public class FishComPare : IEqualityComparer<Fish>
    {

        public bool Equals(Fish x, Fish y)
        {
            return x.Name == y.Name && x.ID==y.ID;
        }

        public int GetHashCode(Fish obj)
        {
            return obj.Name.GetHashCode();
        }
    }

然后全部代码

   class Program
    {
        static void Main(string[] args)
        {
            List<Fish> a = new List<Fish>();
            a.Add(new Fish() { Name = "测试1", ID = 0, Message = "" });
            a.Add(new Fish() { Name = "测试2", ID = 1, Message = "" });
            a.Add(new Fish() { Name = "测试3", ID = 2, Message = "" });
            a.Add(new Fish() { Name = "测试4", ID = 3, Message = "" });
            List<Fish> b = new List<Fish>();
            b.Add(new Fish() { Name = "测试1", ID = 0, Message = "" });
            b.Add(new Fish() { Name = "测试3", ID = 5, Message = "" });
            b.Add(new Fish() { Name = "测试5", ID = 6, Message = "" });


              List<Fish> c = a.Union(b,new FishComPare()).ToList();
              //List<Fish> c = a.Intersect(b,,new FishComPare()).ToList();
            foreach (var item in c)
            {
                Console.WriteLine("Name:{0},ID:{1}", item.Name, item.ID);
            }
            Console.ReadLine();
        }

    }

    public class Fish
    {
        public string Name { get; set; }
        public int ID { get; set; }
        public string Message { get; set; }
    }

    public class FishComPare : IEqualityComparer<Fish>
    {

        public bool Equals(Fish x, Fish y)
        {
            return x.Name == y.Name && x.ID==y.ID;
        }

        public int GetHashCode(Fish obj)
        {
            return obj.Name.GetHashCode();
        }
    }

运行

得到我们想要的结果了,同理,交集也是同样方法

如果我想以Name来比较怎么办,也就是说 我想把”测试3“相同的当一样的,不管ID是否相同,那也好办,我么只需要

    public class FishComPare : IEqualityComparer<Fish>
    {

        public bool Equals(Fish x, Fish y)
        {
            return x.Name == y.Name;
        }

        public int GetHashCode(Fish obj)
        {
            return obj.Name.GetHashCode();
        }
    }

然后我们继续求并集,得到如下结果

也就是说 我们可以以一个类中的一个元素来当做比较对象,这种方式要省了很大力气,虽然遍历循环也能实现,但是有方便的何不拿来直接用呢

posted @ 2012-07-20 17:30  爱喝可乐  阅读(4930)  评论(0编辑  收藏  举报