簡體   English   中英

c#:在字典上迭代時避免分支

[英]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 是一個數字,說明了樣本的一些情況:

  • 如果數字等於0或1,則樣品合格;
  • 如果數字等於 2,那么你稱它為孤立的
  • 如果這個數字等於 3,那么你稱之為 Biased。

所有更高的數字對你來說都不有趣。

您想將樣本分組為通過/隔離/偏差樣本。

每當您有一系列相似的項目並且想要創建項目組時,其中每個元素與組中的其他元素都有共同點,請考慮使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM