Reputation: 2661
I have a generic List<Package>
called packages
.
I invoke for each item the method VersionControlGetStatus()
from Package
class. The method returns an integer value.
List<EA.Package> list = packages.ForEach(p => p.VersionControlGetStatus());
I would like to map the items in the list according to the returned value from the method to create several List<Package>
according the returned values.
How should I update the code above?
EDIT:
For example I have 3 items in packages
list: a
, b
, c
.
When I invoke the method for each item, the returned value for a
and b
is 1.
The returned value for c
is 8.
Desired result:
Two new List<Package>
s; the first contains a
and b
, the second contains c
.
Upvotes: 0
Views: 179
Reputation: 27609
Try code based on the following:
IEnumerable<IGrouping<int, EA.Package>> groupedPackages = packages.GroupBy(p => p.VersionControlGetStatus());
foreach (IGrouping<int, EA.Package> packageGroup in groupedPackages)
{
Console.WriteLine("Status: " + packageGroup.Key.ToString());
Console.WriteLine("Packages:");
foreach (EA.Package package in packageGroup)
{
Console.WriteLine(package.ToString());
}
Console.WriteLine();
}
The first line creates an IEnumerable<IGrouping<>>
. The IGrouping
is basically an IEnumerable
that has the key used to group on it. WE can thus loop over our groupedPackages to get a packageGroup
that has a key and do with that what we want. We then can loop over that packageGroup
as we would any other enumerable and do what we want.
You can also do things like create a lookup from the original list to allow you to easily access a specific status with something like:
Lookup<int, EA.Package> packageLookup = packages.ToLookup(p=>p.VersionControlGetStatus());
IEnumerable<EA.Package> status0Packages = packageLookup[0];
Which is better for you depends on how you are going to use them.
Note: all code has been written directly into this editor window and is untested so may contain minor syntax errors or typos.
Upvotes: 1
Reputation: 7419
I would use GroupBy()
as Typist suggested, but work with the groupings directly. They contain a list of packages and a Key:
IEnumerable<IGrouping<int,Package>> groups = packages.GroupBy(p => p.VersionControlGetStatus()).OrderBy(g => g.Key);
foreach(IGrouping<int,Package> g in groups)
{
Console.WriteLine("Key: {0} | Count: {1}", g.Key, g.Count());
Package first = g.First();
Console.WriteLine("First package in group: " + first.ToString());
}
And if you want packages with a certain status:
List<Package> value1Packages = groups.Single(g => g.Key == 1).ToList();
Edit: included explicit types instead of var for clarity
Upvotes: 2
Reputation: 1474
Use Linq GroupBy
clause
var listOfPackages = packages.GroupBy(p => p.VersionControlGetStatus())
.Select(g => g.ToList());
listOfPackages
is an IEnumerable<List<package>>
This will give you 2 lists according to your example. And you can access the package from the 2 returned lists like below -
foreach(var packageList in listOfPackages) {
foreach(var pack in packageList ) {
// work with your pacakge
}
}
Upvotes: 2