假如我有两个集合:

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. Merge Into

    Merge Into [dbo].[Student] S using [10.58.8.224\TEST].[TestDb].[dbo].[Student] T on S.ID=T.ID WHEN M ...

  2. Leetcode 345 Reverse Vowels of a String 字符串处理

    题意:倒置字符串中的元音字母. 用两个下标分别指向前后两个相对的元音字母,然后交换. 注意:元音字母是aeiouAEIOU. class Solution { public: bool isVowel ...

  3. 生成读取相关连接的物理地址的lib(动态导入库)和dll(动态链接库)

    一.导出相关dll库 将原先的CmdInfoToPipe.h class后加入关键字 __declspec(dllexport) #ifndef NETINFO_CMDINFOTOPIPE_H_ #d ...

  4. PHP实现微信公众账号开发

    1.首先需要一个可以外网访问的接口url. 我这里是申请的新浪免费云服务器,http://xxxxx.applinzi.com/wx.php,具体自己可以去新浪云中心申请地址为:http://www. ...

  5. H5小游戏的坑点小结

    坑点: 1) iOS 9.1 的safari中,在onTouchBegan方法中调用cc.audioEngine.playEffect播放音效是没有效果的,如果在onTouchEnded调用则是正常的 ...

  6. ClamAV安装使用及API例子

    ClamAV是一款由Sourcefire组织开发的开源杀毒引擎,Sourcefire同时也是Snort入侵检测引擎的所有者.ClamAV提供了一种更为快速灵活的框架用以检测恶意代码和软件产品.可以作为 ...

  7. 从《BLAME!》说开去——新一代生产级卡通真实感混合的渲染方案

    <BLAME!>是Polygon Pictures Inc.(以下简称PPI)创业33周年以来制作的第一部CG剧场电影,故事来自于贰瓶勉的同名漫画作品(中文译名为<探索者>或者 ...

  8. TCP_NODELAY 和 TCP_CORK主要区别

    一句话总结: tcp_nodelay:禁止nagle算法,有需要发送的就立即发送,比较常见 tcp_cork:它是一种加强的nagle算法,过程和nagle算法类似,都是累计数据然后发送.但它没有 n ...

  9. 面包板入门电子制作(class1)视频 全套30集高清

    面包板入门电子制作(class1)套件(30集高清) 本套件以电子制作中最基础的元器件在面包板上搭建电路,用启发性的视频教学方式,使学习者熟悉电子电路基础.发挥想像力.在创新设计和制作中学会独立设计和 ...

  10. 正则表达式工具RegexBuddy使用教程(原创自Zjmainstay)

    从<我眼里的正则表达式(入门)>这个文章,到<深入正则表达式应用>,再到后来专门创建的正则QQ群"专精正则表达式",到现在已经过去2年时间了.在文章和群里一 ...