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?

+3


source to share


4 answers


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 ...

+9


source


Why not just keep it simple and store those specific objects in another list?



+1


source


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

      

0


source


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

      

0


source







All Articles