实现具有多个搜索键和值的字典

时间:2019-12-20 21:55:08

标签: c# dictionary data-structures lookup

我在计划表中有40,000行的列表,其值基于五个关键列。表格看起来像这样-

Date    Location    Schedule Id Type    Lane    Value
1/1/2019    Paris   Sched - 1   Rural   <null>  34.94
1/1/2019    Paris   Sched - 1   Rural   <null>  35.41
1/1/2019    Paris   Sched - 1   Rural    101    39.45
1/1/2019    Paris   Sched - 1   Urban    101    94.23
1/1/2019    Paris   Sched - 1   <null>   101    24.87
1/1/2019    Paris   Sched - 1   <null>  <null>  33.38

我需要处理数百万条记录,以便根据每个记录中的键查找值。记录可以包含键的任何组合,其中前三个键是必需的,但后两个键可以具有或可以不具有值。 Schedule表在这五个键的组合中具有唯一的行

我正在寻找有关用于存储计划表的正确数据结构的建议。我曾考虑过使用List,但据我了解,List的效率不如Dictionary,但是只能用一个键定义字典。

感谢有人可以提出更好的方法来实施此解决方案。

--- Edit --

小修正。通过“但接下来的两个键可能有也可能没有值”。我的意思是,它们可能具有空值,但前5个键的组合仍将保持唯一。

2 个答案:

答案 0 :(得分:0)

使用Dictionary<ScheduleTableKey, double>(假设值的类型为double),其中ScheduleTableKey是由所有键列组成的结构。您将获得接近O(1)的复杂度。

例如:

struct ScheduleTableKey {
    DateTime Date;
    string   Location;
    string   Schedule_Id;
    string   Type;
    int?     Lane;
}

var table = new Dictionary<ScheduleTableKey, double>();

请注意,根据您的情况,不同类型的结构成员可能更合适。

答案 1 :(得分:0)

Dictionary会占用所有键和值的存储空间,但是从40,000条记录中创建仅需花费百分之一秒的时间,因此您可以非常有效地查找值。

假设src是包含计划表的IEnumerable<>,则可以使用以下方式将其转换为字典

var ValueMap = src.ToDictionary(s => new { s.Date, s.Location, s.ScheduleId, s.Type, s.Lane }, s => s.Value);

然后您可以使用以下方法查找值:

var k = new { Date, Location, ScheduleId, Type, Lane };
var value = ValueMap[k];

如果您不知道明细表中是否存在特定的键,则可以使用

if (ValueMap.TryGetValue(k, out var value)) {
    // use value here
}
else {
    // there is no matching value
}

如果使用ValueTuple,则可以使用var ValueMap = src.ToDictionary(s => (s.Date, s.Location, s.ScheduleId, s.Type, s.Lane), s => s.Value); var k = (Date, Location, ScheduleId, Type, Lane); var value = ValueMap[k]; (例如C#7)进行处理,并且在进行数百万次查找时不会产生任何垃圾。

Evidence
相关问题