去掉集合里相同数据的对象与求两个对象集合的差集的方法

参考资料:

http://www.cnblogs.com/A_ming/archive/2013/05/24/3097062.html

 

为了方便,先定义一个 foreach 的扩展方法:

        /// <summary>
        /// 循环执行方法。
        /// </summary>
        /// <typeparam name="TSource">对象类型。</typeparam>
        /// <param name="enumerable">对象列表。</param>
        /// <param name="action">方法。</param>
        public static void ForEach<TSource>(this IEnumerable<TSource> enumerable, Action<TSource> action)
        {
            foreach (var item in enumerable)
            {
                action(item);
            }
        }

 

去重复:

        /// <summary>
        /// 通过使用相等比较器对值进行比较返回序列中的非重复元素。
        /// </summary>
        /// <remarks>
        /// 示例1:var query = items.DistinctBy(p => p.Id);
        /// 示例2:var query = items.DistinctBy(p => new { p.Id, p.Name });
        /// </remarks>
        /// <typeparam name="TSource">集合类型。</typeparam>
        /// <typeparam name="TKey">比较元素的类型。</typeparam>
        /// <param name="source">集合。</param>
        /// <param name="keySelector">相等比较器(即:选择通过哪个元素来比较)。</param>
        /// <returns>非重复元素的集合。</returns>
        public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
        {
            var seenKeys = new HashSet<TKey>();

            return source.Where(element => seenKeys.Add(keySelector(element)));
        }

使用方法:

例子里通过使用 Person.Id 来做为对象的标识,所以,会过虑掉该集合中重复 ID 的元素。

即:返回结果里 ID = 2 的两个元素被去掉一个了。

    internal class Program
    {
        private static void Main(string[] args)
        {
            var items = new List<Person>
            {
                new Person {Id = 1, Name = "1111"},
                new Person {Id = 2, Name = "2222"},
                new Person {Id = 2, Name = "2222"},
                new Person {Id = 3, Name = "3333"}
            };

            var query = items.DistinctBy(item => item.Id);

            query.ForEach(item => Console.WriteLine("id={0},name={1}", item.Id, item.Name));

            Console.Read();
        }
    }

    public class Person
    {
        public int Id { get; set; }

        public string Name { get; set; }
    }

 

 

交集:

        /// <summary>
        /// 通过使用相等比较器对值进行比较生成两个序列的差集。
        /// </summary>
        /// <remarks>
        /// 即:返回所有属于 source 集合且不属于 target 集合的元素构成的集合。
        /// 示例1:var query = items1.ExceptBy(items2, item => item.Id);
        /// 示例2:var query = items.ExceptBy(items2, p => new { p.Id, p.Name });
        /// </remarks>
        /// <typeparam name="TSource">集合类型。</typeparam>
        /// <typeparam name="TKey">比较元素的类型。</typeparam>
        /// <param name="source">源集合。</param>
        /// <param name="target">过虑集合。</param>
        /// <param name="keySelector">相等比较器(即:选择通过哪个元素来比较)。</param>
        /// <returns>source 集合与 target 集合的差集。</returns>
        public static IEnumerable<TSource> ExceptBy<TSource, TKey>(this IEnumerable<TSource> source, IEnumerable<TSource> target, Func<TSource, TKey> keySelector)
        {
            var seenTargets = new HashSet<TKey>();

            target.ForEach(item => seenTargets.Add(keySelector(item)));

            var result = source.Where(element =>
            {
                var added = seenTargets.Add(keySelector(element));

                if (added)
                {
                    seenTargets.Remove(keySelector(element));
                }

                return added;
            });

            return result;
        }

使用方法:

例子里通过使用 Person.Id 来做为对象的标识,所以,会过虑掉两个集合中都存在相同 ID 的元素。

即:返回结果里 ID = 1 的元素被去掉了。

    internal class Program
    {
        private static void Main(string[] args)
        {
            var items = new List<Person>
            {
                new Person {Id = 1, Name = "1111"},
                new Person {Id = 2, Name = "2222"},
                new Person {Id = 2, Name = "2222"},
                new Person {Id = 3, Name = "3333"}
            };

            var items2 = new List<Person>
            {
                new Person {Id = 1, Name = "1111"}
            };

            var query = items.ExceptBy(items2, item => item.Id);

            query.ForEach(item => Console.WriteLine("id={0},name={1}", item.Id, item.Name));

            Console.Read();
        }
    }

    public class Person
    {
        public int Id { get; set; }

        public string Name { get; set; }
    }

 

posted @ 2015-07-03 17:04  cjnmy36723  阅读(873)  评论(0编辑  收藏  举报