LaLaLottie
LaLaLottie

Reputation: 403

C# - Inserting Dictionary Keys/Values into New Tuple

I've read some similar posts, but many are just asking about inserting dictionaries into tuples and vice versa. My issue is that I have two separate dictionaries that I want to use to fill in a new tuple.

The the two dictionaries have some common information, which is the user's email. The addressBook dictionary holds the user's name and the user's email. The usersAndManagersList holds the user's email and the manager's email. I was hoping to match up the two then put all bits of information into a single tuple to easily pass around this instead of two dictionaries.

public static Tuple<string, string, string> allUserInformation(Dictionary<string, string> addressBook, Dictionary<string, string> usersAndManagersList)
    {
        Tuple<string, string, string> allUserInfo;

        foreach (var thing in addressBook)
        {
            foreach (var that in usersAndManagersList)
            {
                if (thing.Value == that.Key)
                {
                    var userName = thing.Key;
                    var userEmail = thing.Value;
                    var managerEmail = that.Value;

                    Console.WriteLine("User: {0}, User's Email: {1}, Manager's Email: {2}", userName, userEmail, managerEmail);

                    allUserInfo = Tuple.Create(userName, userEmail, managerEmail);
                }
            }
        }

        return allUserInfo; 
    }

The values in the addressBook and the keys in the usersAndManagersList are both the users' emails. I was trying to loop through everything and if the values of one match up with the keys of the other, then the user's email, user's name, and manager's email will be used to create a tuple, then starts over in the loop.

Main struggles: I'm stuck if I should use a while or if loop. I'm worried about scope and where exactly should I return the tuple. An error I've gotten is that I'm returning an empty/unassigned tuple, which I understand why based on where I returned it, but I'm not sure how to fix it. How do I create this tuple with the right loops, etc.? Thank you in advance.

Upvotes: 1

Views: 1466

Answers (3)

johnny 5
johnny 5

Reputation: 20987

You can use a join or a where statement to match them on a condition and then select the tuple from the results selector. Join is a more complicated logic but has better performance. While the where is more readable to most people

//Assuming that addressBook value (the users email) is the key for the usersAndManagersList

var results = addressBook.Join(usersAndManagersList, addr => addr.Value, user => user.Key, (a, u) => {
    var userName = a.Key;
    var userEmail = a.Value;
    var managerEmail = u.Value;
    return Tuple.Create(userName, userEmail, managerEmail);
}).ToList();

Upvotes: 0

Andrzej Martyna
Andrzej Martyna

Reputation: 475

Despite the fact that JRLambert answer is the best I desided to put some very long and "classic" approach which might be more readable for somebody who don't know LINQ.

   class Program

{

  public static IEnumerable<Tuple<string, string, string> > AllUserInformation(Dictionary<string, string> addressBook, Dictionary<string, string> usersAndManagersList)
  {
     foreach (var book in addressBook)
     {
        string managerEmail;
        if (usersAndManagersList.TryGetValue(book.Value, out managerEmail))
        {
           yield return Tuple.Create(book.Key, book.Value, managerEmail);
        }
        else
        {
           yield return Tuple.Create(book.Key, book.Value, string.Empty);
        }
     }
  }

  static void Main(string[] args)
  {
     Dictionary<string, string> addressBook = new Dictionary<string, string>();
     Dictionary<string, string> usersAndManagersList = new Dictionary<string, string>();
     addressBook.Add("Andy", "[email protected]");
     addressBook.Add("Mary", "[email protected]");
     usersAndManagersList.Add("[email protected]", "[email protected]");

     foreach (var allInfo in AllUserInformation(addressBook, usersAndManagersList))
     {
        Console.WriteLine("User: {0}, User's Email: {1}, Manager's Email: {2}", allInfo.Item1, allInfo.Item2, allInfo.Item3);
     }
  }

}

Upvotes: 1

Jacob Lambert
Jacob Lambert

Reputation: 7679

You can do what you want with LINQ:

addressBook.Where(a => usersAndManagersList.ContainsKey(a.Value))
    .Select(a => Tuple.Create(a.Key, a.Value, usersAndManagersList[a.Value]))

Upvotes: 3

Related Questions