C# Dictionary loop to create a new Dictionary by value object attribute

还是比较喜欢 Using LINQ’s ToDictionary() 这个方法。

        // Option 2: Using LINQ's ToDictionary() method (more concise)
        Dictionary<string, int> peopleAgeByNameLinq = peopleByName.ToDictionary(
            personEntry => personEntry.Value.Name, // Key selector
            personEntry => personEntry.Value.Age   // Value selector
        );

这个有点像是 Java 中的流处理,比较简洁。

To create a new Dictionary based on values from an existing Dictionary in C#, you can iterate through the original dictionary and populate a new one. Here’s an example:

Let’s say you have a Dictionary<string, Person> where Person is a class with properties like Name and Age. You want to create a new Dictionary<string, int> where the key is the person’s name and the value is their age.

using System;
using System.Collections.Generic;
using System.Linq;

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string City { get; set; }
}

public class Example
{
    public static void Main(string[] args)
    {
        // Original Dictionary
        Dictionary<string, Person> peopleByName = new Dictionary<string, Person>
        {
            { "Alice", new Person { Name = "Alice", Age = 30, City = "New York" } },
            { "Bob", new Person { Name = "Bob", Age = 24, City = "London" } },
            { "Charlie", new Person { Name = "Charlie", Age = 35, City = "Paris" } }
        };

        // Option 1: Using a foreach loop
        Dictionary<string, int> peopleAgeByName = new Dictionary<string, int>();
        foreach (var entry in peopleByName)
        {
            peopleAgeByName.Add(entry.Value.Name, entry.Value.Age);
        }

        Console.WriteLine("New Dictionary (foreach loop):");
        foreach (var entry in peopleAgeByName)
        {
            Console.WriteLine($"Key: {entry.Key}, Value: {entry.Value}");
        }
        Console.WriteLine();

        // Option 2: Using LINQ's ToDictionary() method (more concise)
        Dictionary<string, int> peopleAgeByNameLinq = peopleByName.ToDictionary(
            personEntry => personEntry.Value.Name, // Key selector
            personEntry => personEntry.Value.Age   // Value selector
        );

        Console.WriteLine("New Dictionary (LINQ ToDictionary):");
        foreach (var entry in peopleAgeByNameLinq)
        {
            Console.WriteLine($"Key: {entry.Key}, Value: {entry.Value}");
        }
        Console.WriteLine();

        // Example: Creating a dictionary where the key is a city and the value is a list of people from that city
        Dictionary<string, List<Person>> peopleByCity = new Dictionary<string, List<Person>>();

        foreach (var entry in peopleByName)
        {
            string city = entry.Value.City;
            if (!peopleByCity.ContainsKey(city))
            {
                peopleByCity[city] = new List<Person>();
            }
            peopleByCity[city].Add(entry.Value);
        }

        Console.WriteLine("New Dictionary (People by City):");
        foreach (var entry in peopleByCity)
        {
            Console.WriteLine($"City: {entry.Key}");
            foreach (var person in entry.Value)
            {
                Console.WriteLine($"  - {person.Name}, {person.Age}");
            }
        }
    }
}

Explanation:

  1. Person Class: We define a simple Person class to hold our data.

  2. peopleByName (Original Dictionary): This is our initial dictionary where the key is a string (e.g., “Alice”) and the value is a Person object.

  3. Option 1: Using a foreach loop:

    • We initialize an empty Dictionary<string, int> called peopleAgeByName.
    • We iterate through each KeyValuePair<string, Person> in peopleByName.
    • For each entry, we access its Value (which is a Person object).
    • We then use entry.Value.Name as the key for the new dictionary and entry.Value.Age as the value.
  4. Option 2: Using LINQ’s ToDictionary() method:

    • This is a more concise and often preferred way to achieve the same result using Language Integrated Query (LINQ).
    • peopleByName.ToDictionary(...) takes two lambda expressions:
      • The first (personEntry => personEntry.Value.Name) specifies how to derive the key for the new dictionary from each element of the original dictionary.
      • The second (personEntry => personEntry.Value.Age) specifies how to derive the value for the new dictionary.
  5. Example: Grouping by a Property: The last example demonstrates how to create a Dictionary<string, List<Person>> where the key is a city and the value is a list of all Person objects residing in that city. This involves checking if the key (city) already exists in the new dictionary and adding a new list if it doesn’t.

When to choose which option:

  • foreach loop: More explicit and easier to understand for beginners. Good when you need more complex logic inside the loop or need to perform side effects.
  • LINQ ToDictionary(): More concise, functional, and often more readable for straightforward transformations. It’s generally preferred for its elegance and brevity when the transformation is simple.

Here’s an illustration of the process: