扩展 IEnumerable<T>,让它根据另一个集合的顺序来排列
2014-04-03 16:47 音乐让我说 阅读(1009) 评论(0) 编辑 收藏 举报假如我有两个集合:
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); } }
运行结果:
谢谢浏览!
作者:音乐让我说(音乐让我说 - 博客园)
出处:http://music.cnblogs.com/
文章版权归本人所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。