我在计划表中有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个键的组合仍将保持唯一。
答案 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