假如我有两个集合:

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 = , Name = "CCC" },
new Teacher{ Id = , Name = "AAA" },
new Teacher{ Id = , Name = "BBB" },
new Teacher{ Id = , Name = "DDD" },
}; IEnumerable<Student> students = new Student[]
{
new Student{ Id = , TeacherId = , UserName = "张三" },
new Student{ Id = , TeacherId = , UserName = "李四" },
new Student{ Id = , TeacherId = , UserName = "王五" },
new Student{ Id = , TeacherId = , 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 = ; 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 = ;
foreach (var item in source)
{
if (condition(item))
{
return i;
}
i++;
}
return -;
}
}

然后测试代码如下:

static void Main(string[] args)
{
IEnumerable<Teacher> teachers = new Teacher[]
{
new Teacher{ Id = , Name = "CCC" },
new Teacher{ Id = , Name = "AAA" },
new Teacher{ Id = , Name = "BBB" },
new Teacher{ Id = , Name = "DDD" },
}; IEnumerable<Student> students = new Student[]
{
new Student{ Id = , TeacherId = , UserName = "张三" },
new Student{ Id = , TeacherId = , UserName = "李四" },
new Student{ Id = , TeacherId = , UserName = "王五" },
new Student{ Id = , TeacherId = , 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);
}
}

运行结果:

谢谢浏览!

扩展 IEnumerable<T>,让它根据另一个集合的顺序来排列的更多相关文章

  1. 管理员技术(六): 硬盘分区及格式化、 新建一个逻辑卷、调整现有磁盘的分区、扩展逻辑卷的大小、添加一个swap分区

    一.硬盘分区及格式化 问题: 本例要求熟悉硬盘分区结构,使用fdisk分区工具在磁盘 /dev/vdb 上按以下要求建立分区: 1> 采用默认的 msdos 分区模式        2> ...

  2. 返回一个集合对象,同时这个集合的对象的属性又是一个集合对象的处理方法(ViewModel)

    如果遇到需要返回一个集合对象,其中该集合中的属性又是一个集合.第一种:可在考虑用外键关联,比如在控制器中可以采用预先加载的方式加载关联的数据,比如 RoleManager.Roles.Include& ...

  3. WorkFlow WF如何为一个集合赋值

    今天刚刚开始学习WorkFlow.无奈WF网络上的学习资料实在太少. 刚刚学到Foreach控制流的使用,需要一个集合参数.经研究,静态赋值可以搞定.动态赋值还没. 首先添加一个List<int ...

  4. PHP的排列组合问题 分别从每一个集合中取出一个元素进行组合,问有多少种组合?

    首先说明这是一个数学的排列组合问题C(m,n) = m!/(n!*(m-n)!) 比如:有集合('粉色','红色','蓝色','黑色'),('38码','39码','40码'),('大号','中号') ...

  5. 将DataTable 存到一个集合当中

    将DataTable 存到一个集合中 此做法来自:http://www.codeproject.com/Articles/692832/Simple-way-of-using-SQL-DataTabl ...

  6. 5.非关系数据库(Nosql)它mongodb:创建一个集合,导出和导入备份, 数据恢复,进出口

     1 固定集合 固定集合值得是事先创建并且大小固定的集合 2 固定集合的特征:固定集合非常像环形队列.假设空间不足,最早文档就会被删除,为新的文档腾出空间.一般来说.固定集合适用于不论什么想要自己 ...

  7. ZOJ 1204 一个集合能组成多少个等式

    Additive equations Time Limit : 20000/10000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other ...

  8. hibernate,createCriteria in条件 是一个集合。list 或 数组等

    hibernate,createCriteria in条件 是一个集合.list 或 数组等 cq.in("states", new String[]{"2", ...

  9. <c:forEach>可以默认的把以逗号分隔的字符串作为一个集合来遍历

    <c:forEach>可以默认的把以逗号分隔的字符串作为一个集合来遍历

随机推荐

  1. 比较用decodeFileDescriptor和decodeFile的区别

    从本地中读取图片,可以用decodeFileDescriptor和decodeFile,至于哪一种方式的耗内存情况作了一次简单对比,可能一次选取6张图片数量过少,貌似区别不大,decodeFileDe ...

  2. 扩展easyui 的表单验证

    easyui 的validatebox()提供了自定义验证的方法,为此我把一些常用的数据验证汇总了一下,代码如下: 代码 $.extend($.fn.validatebox.defaults.rule ...

  3. asp.net 读取RedisSessionStateProvider配置

    最近项目遇到需要读取RedisSessionStateProvider配置文件applicationName节点,如: 读取的方法有很多: 1直接读取web.config文件, void test1( ...

  4. typeid详解

    在揭开typeid神秘面纱之前,我们先来了解一下RTTI(Run-Time Type Identification,运行时类型识别),它使程序能够获取由基指针或引用所指向的对象的实际派生类型,即允许“ ...

  5. Android——GridView(网格视图)相关知识总结贴

    Android API中文文档GridView http://www.apkbus.com/android-14131-1-1.html   Android API 中文 (15) —— GridVi ...

  6. IOC性能对比

  7. 文档大师 搜狗拼音无法输入汉字_乱码的解决方法_VB6程序

    文档大师用 搜狗拼音无法输入汉字,显示的内容和输入的内容不一致.解决方法: 把中文输入里面的那个“美式键盘”再删掉就好用了,只保留搜狗输入法即可!

  8. 聊聊CSS postproccessors

      阿里妈妈 @一丝 准备发布其CSSGrace,即CSS后处理插件,于是顺便聊聊CSS postprocessors. 从Rework说起 Rework是TJ大神开发的CSS预处理框架.但为什么会出 ...

  9. 每日英语:A Whiff Of 'Welcome Home'

    Buying real estate involves weighing a lot of factors: location, price . . . smell? Some condo devel ...

  10. CSRF - 空Referer绕过

    在实际环境中,服务器很多CGI由于一些历史原因,必须允许空Referer的请求.比如:老的客户端版本请求的时候就没有Referer,总不能在服务端一刀切,让老版本的用户都无法正常使用了吧. 这样的CG ...