实际开发中,遇到一个问题,即在某个对象下的list下,还有list,再获取某个字段的所有数据,类结构层级如下:
public sealed class accountbooks
{
public DateTime CreateDate { get; set; }
public string Version { get; set; }
public List<AccountInfo> AccountList { get; set; }
}
public sealed class AccountInfo
{
public string AccountTitle { get; set; }
public string Describe { get; set; }
public List<AcountRecord> recordList { get; set; }
}
public sealed class AcountRecord
{
public string Name { get; set; }
public int Money { get; set; }
public string Remark { get; set; }
}
这里,我们要获取所有的Money大于零的数据,有如下方式:
第一种很简单直接,用遍历,然后用一个List泛型变量来保存
List<AcountRecord> showList = new List<AcountRecord>();
//第一种方式
foreach (var item in GlobalParams.accountbooks.AccountList)
{
showList.AddRange(item.recordList.Where(x => x.Money >= 0).ToList());
}
第二种也差不多,只是写起来代码更少而已,本质上效率没变
List<AcountRecord> showList = new List<AcountRecord>();
//第二种方式
GlobalParams.accountbooks.AccountList.ForEach(s => showList2.AddRange(s.recordList.Where(a => a.Money >= 0).ToList()));
第三种方式既简洁也没有像上面引入变量,同时也能为可能的二次操作提供保障,例如加入Skip和Take操作
//第三种方式
IEnumerable<AcountRecord> showList = GlobalParams.accountbooks.AccountList.SelectMany(a => a.recordList.Where(b => b.Money >= 0));
上面三种方式,第三种是最好的,因为前面两种都进行了所有数据的处理,所有数据都通过了ToList()方法进行处理。而第三种如果要直接处理所有数据,可以直接ToList(),如果还需要二次操作的话,还可以在此基础上进行Skip和Take之类操作,在集合执行过程时,就会只处理Skip和Take过滤后的数据,因此大量数据的情况下通常效率也是最高的。SelectMany,此时真可谓妙用啊。