[英]c# : avoid branching while iterating on a dictionary
我有下面的代码,其中我为字典中的每个样本分支,有没有办法通过使用 LINQ 或任何其他我可以避免分支的方法 - >可能是一种功能方法
Dictionary<string, int> samples = new Dictionary<string, int>()
{
{"a", 1},
{"aa", 2},
{"b", 1},
{"bb", 3}
};
foreach (var sample in samples)
{
if (sample.Value ==)
{
Console.WriteLine("sample passed");
}
else if (sample.Value == 2)
{
Console.WriteLine("sample isolated");
}
else if (sample.Value == 3)
{
Console.WriteLine("sample biased");
}
}
UPD
如果我有其他类型的比较怎么办:
foreach (var sample in samples)
{
if (sample.Value <= 1)
{
Console.WriteLine("sample passed");
}
else if (sample.Value <= 2)
{
Console.WriteLine("sample isolated");
}
else if (sample.Value <= 3)
{
Console.WriteLine("sample biased");
}
}
一种选择是创建您希望执行的Action
列表,然后根据索引执行它们。 这样,您的方法可以多种多样。 如果您需要为每个选项执行非常相似的操作,那么存储值列表将比存储操作更好。
List<Action> functions = new List<Action>();
functions.Add(() => Console.WriteLine("sample passed"));
functions.Add(() => Console.WriteLine("sample isolated"));
functions.Add(() => Console.WriteLine("sample biased"));
foreach (var sample in samples)
{
Action actionToExecute = functions[sample.Value - 1];
actionToExectute();
}
如果您想使用字典,因为您的评论暗示:
Dictionary<int, Action> functions = new Dictionary<int, Action>();
functions.Add(1, () => Console.WriteLine("sample passed"));
functions.Add(2, () => Console.WriteLine("sample isolated"));
functions.Add(3, () => Console.WriteLine("sample biased"));
foreach (var sample in samples)
{
Action actionToExecute = functions[sample.Value];
actionToExectute();
}
对于这个具体案例,您可以引入另一个映射( Dictionary
或数组,就像我所做的那样):
Dictionary<string, int> samples = new Dictionary<string, int>()
{
{"a", 1},
{"aa", 2},
{"b", 1},
{"bb", 3}
};
var map = new []
{
"sample passed",
"sample isolated",
"sample biased"
};
foreach (var sample in samples)
{
Console.WriteLine(map[sample.Value - 1]);
}
至于实际代码,它在很大程度上取决于用例以及您希望如何处理错误情况。
UPD
看来,如果您将为 map 使用字典,仍然会有一些分支,但如果您不会错过分支预测,则应该注意它。
所以你有一个Dictionary<string, int>
。 字典中的每一项都是KeyValuePair<string, int>
。 我假设字符串是样本的名称(标识符),而 int 是一个数字,说明了样本的一些情况:
所有更高的数字对你来说都不有趣。
您想将样本分组为通过/隔离/偏差样本。
每当您有一系列相似的项目并且想要创建项目组时,其中每个元素与组中的其他元素都有共同点,请考虑使用Enumerable.GroupBy的重载之一
让我们首先定义一个枚举来保存您的资格,以及将样本的 integer 值转换为枚举的方法:
enum SampleQualification
{
Passed,
Isolated,
Biased,
}
SampleQualification FromNumber(int number)
{
switch (number)
{
case 2:
return SampleQualification.Isolated;
case 3:
return SampleQualification.Biased;
default:
return SampleQualification.Passed;
}
}
好的,所以你有了样本字典,其中每个键都是样本的名称,值是可以转换为 SampleQualification 的数字。
Dictionary<string, int> samples = ...
var qualifiedSamples = samples // implements IEnumerable<KeyValuePair<string, int>>
// keep only samples with Value 0..3
.Where(sample => 0 <= sample.Value && sample.Value <= 3)
// Decide where the sample is Passed / Isolated / Biased
.Select(sample => new
{
Qualification = FromNumber(sample.Value)
Name = sample.Key, // the name of the sample
Number = sample.Value,
})
// Make groups of Samples with same Qualification:
.GroupBy(
// KeySelector: make groups with same qualification:
sample => sample.Qualification,
// ResultSelector: take the qualification, and all samples with this qualification
// to make one new:
(qualification, samplesWithThisQualification) => new
{
Qualification = qualification,
Samples = samplesWithThisQualification.Select(sample => new
{
Name = sample.Name,
Number = sample.Number,
})
.ToList(),
});
结果是一系列项目。 每个项目都有一个属性 Qualification,它持有 Passed/Isolated/Biased。 每个项目还有一个具有此资格的样品列表。
// Process Result
foreach (var qualifiedSample in qualifiedSamples)
{
Console.WriteLine("All samples with qualification " + qualifiedSample.Qualification);
foreach (var sample in qualifiedSample.Samples)
{
Console.WriteLine({0} - {1}, sample.Name, sample.Value);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.