Split list <T>?
I have a large list of objects where I sometimes need to iterate over the entire list, and sometimes I only want to look at objects where .Property = "somevalue".
I am currently reviewing my collection .Where(_ => _.Property="value_i_need")
, which is expensive if I have 100k items loaded and only my group is in my target group.
So, I would like the list to be segmented, perhaps how Dictionary<string, List<T>>
, so that I can quickly reference only the set of objects I want, but if I do, how can I list all objects in all dictionaries using Linq without using anymore memory to maintain a regular list?
source to share
Well it looks like you want Lookup
:
var lookup = list.ToLookup(x => x.Property);
You can iterate over the entire collection easily by simply flattening:
foreach (var entry in lookup.SelectMany(x => x))
{
}
... but it won't be in the original order of the list (unless you are very lucky :) If you need to keep the original order of the list, you will need to do a bit of work ...
source to share
Here's how you can do it with a dictionary:
(for example Customer and CustomerStatus):
public class Customer
{
public string Name
{
get;
set;
}
public CustomerStatus Status
{
get;
set;
}
}
public enum CustomerStatus
{
Pending = 0,
Active = 1,
Deleted = 2
}
// Create the dictionary based upon the "filters":
var dictionary = new Dictionary<CustomerStatus, ICollection<Customer>>();
dictionary.Add(CustomerStatus.Active, new List<Customer>());
dictionary.Add(CustomerStatus.Deleted, new List<Customer>());
dictionary.Add(CustomerStatus.Pending, new List<Customer>());
// Add some customers:
dictionary[CustomerStatus.Active].Add(new Customer
{
Name = "Active 1"
});
dictionary[CustomerStatus.Active].Add(new Customer
{
Name = "Active 2"
});
dictionary[CustomerStatus.Deleted].Add(new Customer
{
Name = "Deleted"
});
dictionary[CustomerStatus.Pending].Add(new Customer
{
Name = "Pending"
});
// Enumerate specific filter or all.
System.Console.WriteLine("Active Customers Only");
foreach (var customer in dictionary[CustomerStatus.Active])
{
System.Console.WriteLine(customer.Name);
}
System.Console.WriteLine("---");
var allCustomers = dictionary.SelectMany(x => x.Value);
System.Console.WriteLine("All Customers");
foreach (var customer in allCustomers)
{
System.Console.WriteLine(customer.Name);
}
source to share
You can have all objects in one list, as well as a dictionary of list indices.
var list = new List<MyType>();
// Fill the list
...
// Create the index dictionary
var propIndexes = list
.Select((obj, i) => new { obj.Property, i })
.GroupBy(x => x.Property)
.ToDictionary(g => g.Key,
g => g.Select(x => x.i).ToList());
// Iterate the objects having one specific property
foreach (int i in propIndexes["value_i_need"]) {
Console.WriteLine(list[i]);
}
source to share