How can I split a shared list (from T) based on the property of a list member?

I have a general list (Foo) that contains n objects of type Foo. One of the properties of Foo is property A. PropertyA can be one of ValueA, ValueB, or ValueC. Is there an easy way to split this into three separate lists, one for ValueA, one for ValueB and one for ValueC?

I can write code that iterates over the original list and adds each item to the new list based on the value of the property, but this doesn't seem to be very convenient to maintain (what if I suddenly get a ValueD, for example?)

** EDIT. I should have mentioned that I am using version 2.0 of the framework.

+3
source share
6

# .Net 2.0 ( ):

 //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);
}

:

List<List<foo>> result = fooList
  .GroupBy(foo => foo.PropertyA)
  .Select(g => g.ToList())
  .ToList();

 ILookup<TypeOfPropertyA, foo>> result = fooList.ToLookup(foo => foo.PropertyA);
+4

# :

  List<List<foo>> result = fooList
    .GroupBy(foo => foo.PropertyA)
    .Select(g => g.ToList())
    .ToList();
+5

3 valueA, valueB valueC ( ):

Dim listA = (From x in myList Where x.PropertyA = ValueA).ToList()
Dim listB = (From x in myList Where x.PropertyA = ValueB).ToList()
...

GroupBy, .


EDIT: 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

.

+5

Enumerable.GroupBy:

var groupings = list.GroupBy(x => x.PropertyA);

foreach(var grouping in groupings)
{
    // grouping.Key is the grouped value

    foreach(var entry in grouping)
    {
        // process
    }
}
+3

# VB.Net - , (FooFinder), VB.NET , -, .

"" , # 2.0. , (looping/dictionaries) FindAll List, , true. #:

using System;
using System.Collections.Generic;

namespace SplitList
{
    class Program
    {
        class Foo
        {
            public Foo(string propertyA, int number)
            {
                _propertyA = propertyA;
                _number = number;
            }

            private int _number;

            private string _propertyA;

            public string PropertyA
            {
                get { return _propertyA; }
            }

            public int Number
            {
                get { return _number; }
            }
        }
        static void Main(string[] args)
        {
            List<Foo> foos = new List<Foo>();
            foos.Add(new Foo("ValueA", 1));
            foos.Add(new Foo("ValueA", 2));
            foos.Add(new Foo("ValueA", 3));
            foos.Add(new Foo("ValueA", 4));
            foos.Add(new Foo("ValueB", 5));
            foos.Add(new Foo("ValueB", 6));
            foos.Add(new Foo("ValueC", 7));
            foos.Add(new Foo("ValueC", 8));
            foos.Add(new Foo("ValueC", 9));

            List<Foo> aFoos = foos.FindAll(delegate(Foo f) { return f.PropertyA == "ValueA"; });
            List<Foo> bFoos = foos.FindAll(delegate(Foo f) { return f.PropertyA == "ValueB"; });
            List<Foo> cFoos = foos.FindAll(delegate(Foo f) { return f.PropertyA == "ValueC"; });
            WriteFoos("ValueA", aFoos);
            WriteFoos("ValueB", bFoos);
            WriteFoos("ValueC", cFoos);
            Console.ReadLine();
        }

        private static void WriteFoos(string propertyAValue, List<Foo> list)
        {
            Console.WriteLine("Group {0}:", propertyAValue);
            list.ForEach(delegate(Foo f)
                             {
                             Console.WriteLine("Number:{0}, PropertyA:{1}", f.Number, f.PropertyA);
                             });

        }
    }
}

VB.NET:

Module Module1

    Class FooFinder
        Public Sub New(ByVal propertyAValue As String)
            Me.PropertyAValue = propertyAValue
        End Sub
        Public ReadOnly PropertyAValue As String
        Function Matches(ByVal f As Foo) As Boolean
            Return (f.PropertyAValue = Me.PropertyAValue)
        End Function
    End Class
    Class Foo

        Public Sub New(ByVal propertyAValue As String, ByVal number As Integer)
            _propertyAValue = propertyAValue
            _number = number
        End Sub

        Private _propertyAValue As String
        Private _number As Integer

        Public Property PropertyAValue() As String
            Get
                Return _propertyAValue
            End Get
            Set(ByVal value As String)
                _propertyAValue = value
            End Set
        End Property

        Public Property Number() As Integer
            Get
                Return _number
            End Get
            Set(ByVal value As Integer)
                _number = value
            End Set
        End Property
    End Class
    Sub Main()

        Dim foos As New List(Of Foo)
        foos.Add(New Foo("ValueA", 1))
        foos.Add(New Foo("ValueA", 2))
        foos.Add(New Foo("ValueA", 3))
        foos.Add(New Foo("ValueB", 4))
        foos.Add(New Foo("ValueB", 5))
        foos.Add(New Foo("ValueC", 6))
        foos.Add(New Foo("ValueC", 7))
        foos.Add(New Foo("ValueC", 8))
        foos.Add(New Foo("ValueC", 9))

        Dim aFoos As List(Of Foo) = foos.FindAll(AddressOf New FooFinder("ValueA").Matches)
        Dim bFoos As List(Of Foo) = foos.FindAll(AddressOf New FooFinder("ValueB").Matches)
        Dim cFoos As List(Of Foo) = foos.FindAll(AddressOf New FooFinder("ValueC").Matches)

        WriteFoos("ValueA", aFoos)
        WriteFoos("ValueB", bFoos)
        WriteFoos("ValueC", cFoos)
        Console.ReadLine()


    End Sub

    Private Sub WriteFoos(ByVal propertyAValue As String, ByVal list As List(Of Foo))
        Console.WriteLine("PropertyAValue:{0}", propertyAValue)
        For Each f As Foo In list
            Console.WriteLine("Number:{0}, PropertyAValue:{1}", f.Number, f.PropertyAValue)
        Next
    End Sub
End Module
+3
var query = from foo in list
            group foo by foo.PropertyA;

List<Foo> valueAGroup = query.First(g => g.Key == ValueA).ToList();
List<Foo> valueBGroup = query.First(g => g.Key == ValueB).ToList();
List<Foo> valueCGroup = query.First(g => g.Key == ValueC).ToList();

ToList(), IEnumerable<Foo> .

, ValueX , PropertyA ValueX, First . :

List<Foo> valueXGroup = (query.FirstOrDefault(g => g.Key == ValueX) ??
    Enumerable.Empty<Foo>()).ToList();

.

+1

Source: https://habr.com/ru/post/1721880/


All Articles