0

This might not be the best way of wording this question but it's kind of what I want to do.

I have a Dictionary that looks like this:

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

I have a List with a bunch of game names like this, with repetition:

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"

What I would like to do is this, iterate through this massive games List, and use the gameLookup Dictionary to assign a score. If the game from the massive games List doesn't exist in the gameLookup, use the 'Empty Game Title n' as the lookup key.

So, Paper Mario would technically be Empty Game 1, The Legend of Zelda would be Empty Game 2, and Street Fighter would be Empty Game 3.

I have tried doing a goto but it doesn't seem to do anything.

Here's my approach:

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;
  }

The reason I think I need to do a goto is because of the repetition. Because if Paper Mario is actually Empty Game Title 1, then without breaking out, it's going to assume the next iteration that is Paper Mario will be Empty Game Title 2, so I would want to keep breaking out but then restarting the loop so it remembers that Paper Mario -> Empty Game Title 1.

I hope that makes sense. This might not be the best approach so by all means, if you think there's a better way.

  • 1
    What is `GroupLookup`? – Tim Schmelter Jul 27 '18 at 13:14
  • A typo on my end. Sorry, I edited it. Not sure what I was doing there. –  Jul 27 '18 at 13:16
  • 2
    wow a `goto` in C#. I haven't seen one of them in years, [yeah never use them](https://stackoverflow.com/questions/6545720/does-anyone-still-use-goto-in-c-sharp-and-if-so-why) – Liam Jul 27 '18 at 13:17
  • You could maybe use Linq `Distinct` on `gameNames` to begin with – Rafalon Jul 27 '18 at 13:17
  • @James I can't see any *"The Legend of Zelda"* in `gameLookup` – Rafalon Jul 27 '18 at 13:20
  • @Liam, I agree this is not a good use of goto, but never is a bit too strong. I used one today to fall through on a switch statement from one case to the next. – Adam G Jul 27 '18 at 14:39
  • You'd typically use `break` for that @AdamG I mean as that posts states there are rare occasions where you need it. If I saw one of my developers using a `goto` I'd make them remove it. – Liam Jul 27 '18 at 14:41
  • @Liam, you cannot use break to fall through. Indeed break forces it to not fall through, the exact opposite of the requirement. The only way c# can implement a fall through on a switch (unless it's empty) is with goto. See https://stackoverflow.com/a/174223/9555136 . It's relatively rare, but necessary. But not the case here. – Adam G Jul 27 '18 at 20:44

3 Answers3

1

I think your missing a yield if your making an iterator. You also need to return an enumeration not a single value:

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!
 }

Your code is also missing vital braces.

Liam
  • 27,717
  • 28
  • 128
  • 190
  • `int startingEmptyGameTitle = 1;` is not `const` and needs to be incremented if there's no match (as it is in OP's question - `startingEmptyGameTitle++;`) – Rafalon Jul 27 '18 at 14:13
  • 1
    Still, this answer lacks the fact that duplicate-non-existing game names will keep increasing this value. I'd suggest using a `Distinct` on `GameNames` (see my comment on OP's question). And, a `;` is missing in the first line of your `if` – Rafalon Jul 27 '18 at 14:17
  • Possibly. I think that's for the OP to decide. corrected missing `;` – Liam Jul 27 '18 at 14:20
  • Well, think about OP example list and dictionary, what scores do you expect the ***three first*** `"Super Mario Bros."` in `gameNames` to yield as it stands? (I'd say: 99, 98 and 92) – Rafalon Jul 27 '18 at 14:24
  • This doesn't exactly do what I want, actually. It increments every other still. –  Jul 31 '18 at 13:19
0

Right now, you use of goto makes you restart your function everytime you have a game that is not in GameLookup. I'm pretty sure that's not what you want to do.

What you want is for your program to ignore the titles that are already empty games titles. So you need to save them somewhere and then check if they are already one of the empty game titles before creating a new empty game title.

Also, I don't think you want your return to be here. As is is now, it will return in your 1st loop iteration and exit the function

Liora Haydont
  • 1,252
  • 1
  • 12
  • 25
0

The version works as expected: https://dotnetfiddle.net/feikWH

In this sample code, gameScore contains score for each distinct game in the games. Suppose that there is always 1 Empty Game Title 1. By your requirement, you should check null in 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;
}
Antoine V
  • 6,998
  • 2
  • 11
  • 34