假设
public class MyClass
{
public int ID {get; set; }
public string Name {get; set; }
}
和
List<MyClass> classList = //populate with MyClass instances of various IDs
我能做到
List<MyClass> result = classList.FindAll(class => class.ID == 123);
这将给我一个ID = 123的类列表。效果很好,看起来很优雅。
现在,如果我有
List<List<MyClass>> listOfClassLists = //populate with Lists of MyClass instances
如何获得筛选列表本身被过滤的筛选列表。我试过了
List<List<MyClass>> result = listOfClassLists.FindAll
(list => list.FindAll(class => class.ID == 123).Count > 0);
它看起来很优雅,但不起作用。它只包含类的列表,其中至少有一个类的ID为123,但它包含该列表中的所有MyClass实例,而不仅仅是匹配的实例。
我最终不得不做
List<List<MyClass>> result = Results(listOfClassLists, 123);
private List<List<MyClass>> Results(List<List<MyClass>> myListOfLists, int id)
{
List<List<MyClass>> results = new List<List<MyClass>>();
foreach (List<MyClass> myClassList in myListOfLists)
{
List<MyClass> subList = myClassList.FindAll(myClass => myClass.ID == id);
if (subList.Count > 0)
results.Add(subList);
}
return results;
}
完成工作,但不是那么优雅。只是寻找更好的方法在列表列表上进行FindAll 肯
答案 0 :(得分:5)
listOfClasses.SelectMany(x =&gt; x).FindAll(/ * yadda * /)
很抱歉,FindAll是List&lt; T&gt;的方法。
此
var result = from x in listOfClasses from y in x where SomeCondition(y) select y;
或
var result = listOfClasses.SelectMany(x=>x).Where(x=>SomeCondition(x));
答案 1 :(得分:2)
要保留列表列表,您可以执行以下示例:
MyClass a = new MyClass() { ID = 123, Name = "Apple" };
MyClass b = new MyClass() { ID = 456, Name = "Banana" };
MyClass c = new MyClass() { ID = 789, Name = "Cherry" };
MyClass d = new MyClass() { ID = 123, Name = "Alpha" };
MyClass e = new MyClass() { ID = 456, Name = "Bravo" };
List<List<MyClass>> lists = new List<List<MyClass>>()
{
new List<MyClass>() { a, b, c },
new List<MyClass>() { d, e },
new List<MyClass>() { b, c, e}
};
var query = lists
.Select(list => list.Where(item => item.ID == 123).ToList())
.Where(list => list.Count > 0).ToList();
查询将List<List<MyClass>>
保存通过测试的MyClass对象列表。乍一看,它看起来乱序,其中Where扩展位于Select之后,但内部列表的转换需要先发生,这就是Select扩展中发生的情况。然后由Where。
答案 2 :(得分:0)
我可能会选择这个
List<List<string>> stuff = new List<List<string>>();
List<List<string>> results = new List<List<string>>();
stuff.ForEach(list=> {var result = list.FindAll(i => i == "fun").ToList();
if (result.Count > 0) results.Add(result);
});
List<string> flatResult = new List<string>();
stuff.ForEach(List => flatResult.AddRange(List.FindAll(i => i == "fun")));
通过这种方式,你可以使用锯齿状阵列或将其展平......但Linq方式也很有效: - )。
答案 3 :(得分:0)
虽然制作广告List<MyClass>
会在大多数情况下满足您的需求,但完全回答您的问题是:
var result = (from list in ListOfClassLists
let listWithTheId=
(
(from myClass in list
where myClass.ID == id
select myClass)
.ToList()
)
where listWithTheId.Count > 0
select listWithTheId
).ToList();
此代码段取自我的概念验证:
using System.Collections.Generic;
using System.Linq;
namespace ListOfListSelectionSpike
{
public class ListSpikeClass
{
public List<List<MyClass>> ListOfClassLists { get; set; }
private List<MyClass> list1, list2, list3;
public ListSpikeClass()
{
var myClassWithId123 = new MyClass("123");
var myClassWithIs345 = new MyClass("456");
list1 = new List<MyClass> { myClassWithId123, myClassWithIs345 };
list2 = new List<MyClass> { myClassWithId123, myClassWithIs345, myClassWithId123 };
list3 = new List<MyClass> { myClassWithIs345, myClassWithIs345 };
ListOfClassLists = new List<List<MyClass>> { list1, list2, list3 };
}
public List<List<MyClass>> GetListOfListsById(string id)
{
var result = (from list in ListOfClassLists
let listWithTheId =
((from myClass in list
where myClass.ID == id
select myClass)
.ToList())
where listWithTheId.Count > 0
select listWithTheId)
.ToList();
return result;
}
}
public class MyClass
{
public MyClass(string id)
{
ID = id;
Name = "My ID=" + id;
}
public string ID { get; set; }
public string Name { get; set; }
}
}