zoukankan      html  css  js  c++  java
  • 扩展 IEnumerable<T>,让它根据另一个集合的顺序来排列

    假如我有两个集合:

    public class Teacher
    {
        public int Id { get; set; }
    
        public string Name { get; set; }
    }
    
    public class Student
    {
        public int Id { get; set; }
    
        public string UserName { get; set; }
    
        public int TeacherId { get; set; }
    }

    集合代码:

    static void Main(string[] args)
    {
        IEnumerable<Teacher> teachers = new Teacher[]
        {
            new Teacher{ Id = 9, Name = "CCC" },
            new Teacher{ Id = 5, Name = "AAA" },
            new Teacher{ Id = 7, Name = "BBB" },
            new Teacher{ Id = 13, Name = "DDD" },
        };
    
        IEnumerable<Student> students = new Student[]
        {
            new Student{ Id = 1, TeacherId = 13, UserName = "张三" },
            new Student{ Id = 2, TeacherId = 5, UserName = "李四" },
            new Student{ Id = 3, TeacherId = 9, UserName = "王五" },
            new Student{ Id = 4, TeacherId = 18, UserName = "赵六" },
        };
    }

    前提条件:students 里面的 TeacherId 大部分来自于 teachers 里的 ID, 也可能不是。
    现在要求:按 teachers 的 顺序 来对 students 里面的项排序。

    我的代码如下:

    首先扩展 IEnumerable<T>

    public static class EnumerableExtensions
    {
        /// <summary>
        /// 按照另一个现有的集合的关联字段来排序
        /// </summary>
        /// <typeparam name="T">类型1</typeparam>
        /// <typeparam name="T2">类型2</typeparam>
        /// <param name="source1">要排序的集合</param>
        /// <param name="source2">参考的集合</param>
        /// <param name="condition">条件</param>
        /// <returns></returns>
        public static IEnumerable<T> OrderByOther<T, T2>(this IEnumerable<T> source1, IEnumerable<T2> source2, Func<T, T2, bool> condition)
        {
            if (source1 == null)
            {
                throw new ArgumentNullException("source1");
            }
            if (source2 == null)
            {
                throw new ArgumentNullException("source2");
            }
            if (condition == null)
            {
                throw new ArgumentNullException("condition");
            }
            int source1Count = source1.Count();
            SortedDictionary<int, T> values = new SortedDictionary<int, T>();
            // 3, 0, 2, -1, -1
            for (int i = 0; i < source1Count; i++)
            {
                var item = source1.ElementAt(i);
                var tempIndex = source2.FirstIndex(s => condition(item, s));
                values.Add(tempIndex, item);
            }
            foreach (var item in values)
            {
                yield return item.Value;
            }
        }
    
        /// <summary>
        /// 得到满足条件的第一个元素在集合中所在的索引
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="source">目标集合</param>
        /// <param name="condition">条件</param>
        /// <returns>如果没有找到,返回 -1</returns>
        public static int FirstIndex<T>(this IEnumerable<T> source, Predicate<T> condition)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
            if (condition == null)
            {
                throw new ArgumentNullException("condition");
            }
            int i = 0;
            foreach (var item in source)
            {
                if (condition(item))
                {
                    return i;
                }
                i++;
            }
            return -1;
        }
    }

    然后测试代码如下:

    static void Main(string[] args)
    {
        IEnumerable<Teacher> teachers = new Teacher[]
        {
            new Teacher{ Id = 9, Name = "CCC" },
            new Teacher{ Id = 5, Name = "AAA" },
            new Teacher{ Id = 7, Name = "BBB" },
            new Teacher{ Id = 13, Name = "DDD" },
        };
    
        IEnumerable<Student> students = new Student[]
        {
            new Student{ Id = 1, TeacherId = 13, UserName = "张三" },
            new Student{ Id = 2, TeacherId = 5, UserName = "李四" },
            new Student{ Id = 3, TeacherId = 9, UserName = "王五" },
            new Student{ Id = 4, TeacherId = 18, UserName = "赵六" },
        };
    
        // 前提条件:students 里面的 TeacherId 大部分来自于 teachers 里的 ID, 也可能不是。
        // 现在要求:按 teachers 的 顺序 来对 students 里面的项排序。
    
        var result = students.OrderByOther(teachers, (a, b) => a.TeacherId == b.Id);
        foreach (var item in result)
        {
            Console.WriteLine("stuId:" + item.TeacherId + ", stuName:" + item.UserName);
        }
    }

    运行结果:

    谢谢浏览!

  • 相关阅读:
    2014第16周六
    2014第16周五
    2014第16周四
    2014第16周三CSS布局再学习摘录
    2014第16周二
    2014第16周一
    2014第15周日
    2014第15周六
    2014第15周五
    SDN:软件定义网络
  • 原文地址:https://www.cnblogs.com/Music/p/ienumberable-extensions.html
Copyright © 2011-2022 走看看