分区列表<t>?</t>

时间:2012-03-09 16:02:21

标签: c# linq collections partitioning

我有一个很大的对象列表,我有时需要遍历整个列表,有时我只想查看.Property =“somevalue”的对象。

目前我查看我的集合.Where(_ => _.Property="value_i_need"),如果我加载了100k对象并且只有少数人在我的目标组中,那么这个集合很昂贵。

所以我想做的是将列表分段保存为Dictionary<string, List<T>>,以便我可以快速引用我想要的对象集,但如果我这样做,怎么能枚举所有的使用Linq的所有字典中的对象,而不使用更多内存来维护常规列表?

4 个答案:

答案 0 :(得分:9)

听起来你想要一个Lookup

var lookup = list.ToLookup(x => x.Property);

只需展平即可轻松迭代整个集合:

foreach (var entry in lookup.SelectMany(x => x))
{
}

...但是这个不会处于初始列表顺序(除非你很幸运:)如果你需要维护原始列表顺序,你需要做一个更多的工作...

答案 1 :(得分:1)

为什么不简单地将它们简单化,并将这些特定对象存储在另一个列表中?

答案 2 :(得分:0)

以下是使用字典的方法:

(例如Customer和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);
}

答案 3 :(得分:0)

您可以将一个列表中的所有对象加上一个列表索引字典。

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