如何在迭代中同时中断和继续?

时间:2018-07-27 13:11:12

标签: c#

这可能不是表达此问题的最佳方式,但这是我想做的。

我有一个像这样的字典:

Dictionary<string, int> gameLookup = new Dictionary<string, int>();

"Empty Game Title 1", 99
"Super Metroid", 98
"Empty Game Title 2", 98
"Final Fantasy VI", 95
"Empty Game Title 3", 92
"Donkey Kong Country", 90

我有一个列表,上面有很多这样的游戏名称,重复出现:

List<string> gameNames = new List<string>();


"Super Mario Bros."
"Super Mario Bros."
"Super Mario Bros."
"Super Metroid"
"Super Metroid"
"Final Fantasy VI"
"Donkey Kong Country"
"Donkey Kong Country"
"Donkey Kong Country"
"Paper Mario"
"Paper Mario"
"The Legend of Zelda"
"The Legend of Zelda"
"The Legend of Zelda"
"Street Fighter"

我想做的是,遍历这个庞大的游戏列表,并使用gameLookup Dictionary来分配分数。如果大型游戏列表中的游戏在gameLookup中不存在,请使用“空游戏标题n”作为查找键。

因此,从技术上讲,Paper Mario将是第1空游戏,《塞尔达传说》将是第2空游戏,而Street Fighter将是第3空游戏。

我尝试做过goto,但似乎什么也没做。

这是我的方法:

public static int PerformLookup(List<string> GameNames, Dictionary<string, int> GameLookup)
{
  Restart:
  int reviewScore = 0;
  int startingEmptyGameTitle = 1;
  foreach (string element in GameNames)
    if (GameLookup.ContainsKey(element))
        reviewScore = GameLookup[element]
    else
     {
       reviewScore = GameLookup["Empty Game Title " + startingEmptyGameTitle]
       startingEmptyGameTitle++;
       goto Restart;
     }
      return reviewScore;
  }

我认为我需要做goto的原因是因为重复。因为如果Paper Mario实际上是Empty Game Title 1,那么它不会中断,而是假设下一个迭代即Paper Mario将是Empty Game Title 2,所以我想继续进行讨论,但是重新启动循环,以便记住该纸Mario->空游戏标题1。

我希望这是有道理的。如果您认为有更好的方法,那么这可能并不是最好的方法。

3 个答案:

答案 0 :(得分:1)

如果您进行迭代,我认为您会错过yield。您还需要返回一个枚举,而不是单个值:

public static IEnumerable<int> PerformLookup(List<string> GameNames, Dictionary<string, int> GameLookup)
{

      int reviewScore = 0;

      int startingEmptyGameTitle = 1;
      foreach (string element in GameNames)
      //this was missing!
      {
        if (GameLookup.ContainsKey(element))
            reviewScore = GameLookup[element];
        else
         {
           //you really need to think about what happens here if this doesn't 
           //match anything in the dictionary!
           if (GameLookup.ContainsKey($"Empty Game Title {startingEmptyGameTitle}"))
                reviewScore = GameLookup[$"Empty Game Title {startingEmptyGameTitle}"];

            startingEmptyGameTitle++;
         }
         yield return reviewScore;
      }
 //and this!
 }

您的代码也缺少大括号。

答案 1 :(得分:0)

现在,您使用goto可使您每次有GameLookup以外的游戏时重新启动功能。我很确定那不是您想要的。

您想要的是程序忽略已经为空的游戏标题的标题。因此,您需要将它们保存在某个地方,然后在创建新的空白游戏标题之前检查它们是否已经是空白游戏标题之一。

此外,我不认为您希望您的return在这里。现在,它将在您的第一个循环迭代中返回并退出函数

答案 2 :(得分:0)

该版本可以正常运行:https://dotnetfiddle.net/feikWH

在此示例代码中,gameScore包含游戏中每个不同游戏的得分。假设总有1个Empty Game Title 1。 根据您的要求,您应在null

中选中gameLookup
public static Dictionary<string, int> PerformLookup(List<string> GameNames, Dictionary<string, int> GameLookup)
{
    Dictionary<string, int> gameScore = new Dictionary<string, int>();
    int n = 0;
    foreach(string game in gameNames)
    {
        if(gameScore.ContainsKey(game))
            continue;
        if(gameLookup.Keys.Contains(game))
        {
            gameScore.Add(game, gameLookup.FirstOrDefault(x=> x.Key == game).Value);
        }          
        else
        {
            n++;
            if(gameLookup.FirstOrDefault(x=> x.Key == "Empty Game Title " + n.ToString()).Value == null)
                n--;
            gameScore.Add(game, gameLookup.FirstOrDefault(x=> x.Key == "Empty Game Title " + n.ToString()).Value);

        }
    }   

    foreach(var t in gameScore)
    {
        Console.WriteLine(t);
    }

    return gameScore;
}