如何根据列表成员的属性拆分通用List(T)?

Sim*_*mon 3 .net vb.net generics .net-2.0

我有一个通用的List(Foo),它包含了Type Foo的n个对象.Foo的一个属性是PropertyA.PropertyA可以是ValueA,ValueB或ValueC之一.有没有一种简单的方法可以将它分成三个单独的列表,一个用于ValueA,一个用于ValueB,一个用于ValueC?

我可以编写一些循环原始列表的代码,并根据属性值将每个项目添加到新列表中,但这似乎不是很容易维护(如果我突然得到一个ValueD,那该怎么办?)

**编辑.我应该提到我正在使用该框架的2.0版本.

Amy*_*y B 5

在C#中我会写:

  List<List<foo>> result = fooList
    .GroupBy(foo => foo.PropertyA)
    .Select(g => g.ToList())
    .ToList();
Run Code Online (Sandbox Code Playgroud)


Hei*_*nzi 5

如果你想要valueA,valueB和valueC的3个列表(即使其中一个是空的):

Dim listA = (From x in myList Where x.PropertyA = ValueA).ToList()
Dim listB = (From x in myList Where x.PropertyA = ValueB).ToList()
...
Run Code Online (Sandbox Code Playgroud)

否则,按照其他人的建议使用GroupBy运算符.


编辑:由于您使用的是Framework 2.0,我想您将不得不求助于您的循环创意.但是,实现GroupBy的通用算法应该不会太困难.有点像

Dim dic as New Dictionary(Of TypeOfYourValues, List(Of Foo))
For Each e As Foo In myList
    If Not dic.ContainsKey(e.PropertyA) Then
        dic(e.PropertyA) = New List(Of Foo)
    End if
    dic(e.PropertyA).Add(e)
Next
Run Code Online (Sandbox Code Playgroud)

然后循环遍历字典的值.


Amy*_*y B 5

在带有.Net 2.0的C#中,我写了很多次:

 //if PropertyA is not int, change int to whatever that type is
Dictionary<int, List<foo>> myCollections =
  new Dictionary<int, List<foo>>();
//
foreach(Foo myFoo in fooList)
{
  //if I haven't seen this key before, make a new entry
  if (!myCollections.ContainsKey(myFoo.PropertyA))
  {
    myCollections.Add(myFoo.PropertyA, new List<foo>());
  }
  //now add the value to the entry.
  myCollections[myFoo.PropertyA].Add(myFoo);
}
//
// now recollect these lists into the result.
List<List<Foo>> result = new List<List<Foo>>();
foreach(List<Foo> someFoos in myCollections.Values)
{
  result.Add(someFoos);
}
Run Code Online (Sandbox Code Playgroud)

如今,我只写:

List<List<foo>> result = fooList
  .GroupBy(foo => foo.PropertyA)
  .Select(g => g.ToList())
  .ToList();
Run Code Online (Sandbox Code Playgroud)

要么

 ILookup<TypeOfPropertyA, foo>> result = fooList.ToLookup(foo => foo.PropertyA);
Run Code Online (Sandbox Code Playgroud)