0

Assume I have a list of class

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

Now i need to convert into List of Dictionary as
Assume it as List<Dictionary<key, value>>PersonDict, below is the structure of each indexes of the same. The key name should be dynamically populated as Property name in the class Person.

key : "Id", Value : Person.Id
key : "Name", Value : Person.Name
key : "Age", Value : Person.Age

Can anyone please help, I have already tried "for each" and "Parallel For each" loop but its taking lot of time, I have 3 millions of record to convert and its taking hours.

Sampan
  • 3
  • 3
  • 2
    You'll probably need to look into [Reflection](https://https://learn.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/reflection). – 41686d6564 stands w. Palestine Feb 16 '19 at 03:13
  • 2
    Possible duplicate of [How to convert class into Dictionary?](https://stackoverflow.com/questions/9210428/how-to-convert-class-into-dictionarystring-string). Just use `Dictionary` instead of `Dictionary` – Alexander Feb 16 '19 at 03:16
  • `List>PersonDict` this is not a valid type please be specific ,this is a coding site – TheGeneral Feb 16 '19 at 03:22
  • Your question is not very clear but list has `ToDictionary` method. – CodingYoshi Feb 16 '19 at 03:24
  • @CodingYoshi , [`ToDictionaty()`](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.todictionary) method allows to create key-value pair for each item of a collection. But OP wants to get list of dictionaries, those contains key-value value pairs for all properties of original collection item. – Alexander Feb 16 '19 at 04:12
  • Why do you want to do this? What is your ultimate girl? To what use will you put your list of dictionaries? – Caius Jard Feb 16 '19 at 04:28
  • The user is unresponsive, gives no clarification, has not added the appropriate information to the question, and as it stands looks like an X/Y problem, voting to close as unclear – TheGeneral Feb 16 '19 at 04:37
  • But this is very time consuming and for Millions of record it takes lot of time, is there any other process ? I need to dynamically map the key name in Dictionary to the objects in the class Person and need to improve the performance also – Sampan Feb 17 '19 at 05:36
  • please try the "duplicate answers", if they don't fit your need, then please emphasize the problem and the difference to the duplicate question (edit question), then I am sure it can be re-opened. – xerx593 Feb 17 '19 at 10:19

2 Answers2

2

Here is a working implementation:

using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        // Create some sample records
        var persons = new List<Person>(){
            new Person(){Id = 1, Name = "Bob", Age = 30},
            new Person(){Id = 2, Name = "Jane", Age = 31},
            new Person(){Id = 3, Name = "Mary", Age = 32}
        };

        // Use Reflection to retrieve public properties
        var properties = typeof(Person).GetProperties();

        // Create a list to store the dictionaries      
        var listOfDictionary = new List<Dictionary<string, string>>();

        // For each person class
        foreach(var person in persons){
            // Create a new dictionary
            var dict = new Dictionary<string,string>();
            // For each property
            foreach(var prop in properties){
                // Add the name and value of the property to the dictionary
                dict.Add(prop.Name, prop.GetValue(person).ToString());

            }
            // Add new dictionary to our list
            listOfDictionary.Add(dict);

        }


        // Check the contents of our list
        foreach(var dict in listOfDictionary){      
            Console.WriteLine(string.Join(",", dict.Keys));
            Console.WriteLine(string.Join(",", dict.Values));
        }

    }

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

You mention that you have millions of records to convert. It may be not the best idea to create millions of Dictionary<> instances, nor to keep them all in memory. However, it is difficult to recommend something without knowing what is your end goal.

Serge
  • 3,986
  • 2
  • 17
  • 37
  • It's possible to use `object` type for dictionary value to store original property values. – Alexander Feb 16 '19 at 03:56
  • @Alexander yes this is true, however this will had boxing overhead as well – TheGeneral Feb 16 '19 at 04:01
  • @MichaelRandall - Have you ever had a situation where the boxing overhead was significant? – Enigmativity Feb 16 '19 at 04:02
  • @Enigmativity if op wants to save every cpu cycle, op will – TheGeneral Feb 16 '19 at 04:03
  • @MichaelRandall - Yes, then you could suggest that they write the code in machine language. But since they are using C# then performance at that extreme may not be their biggest goal. – Enigmativity Feb 16 '19 at 04:07
  • @Serge foreach loop for 3 millions of record will take hours to compute, is there any feasible way to do it. – Sampan Feb 17 '19 at 05:39
  • @MichaelRandall `ToString()` has much more overhead than boxing – Ivan Stoev Feb 17 '19 at 11:42
  • @Sampan `foreach` loop is quite fast. The slowest part is creating the dictionaries. Even with the reflection calls, the above method takes ~4 seconds (not hours!) to complete for list containing 3 million `Person` elements. If your code runs for hours, the problem is somewhere else. Update the post with relevant information and test code/data which can be run and verified (i.e. [mcve]) and it can eventually be reopened. – Ivan Stoev Feb 17 '19 at 19:04
2

This is pretty much the same as the other answers here, but using a slightly more terse syntax. Just a matter of preference.

List<Person> persons = new List<Person> {
    new Person { Id = 1, Name = "Sally", Age = 10 },
    new Person { Id = 2, Name = "Bob", Age = 9 },
};

List<Dictionary<string, string>> listOfDictionaries =
    persons
        .Select(p => new Dictionary<string, string>
        {
            ["Id"] = p.Id.ToString(),
            ["Name"] = p.Name,
            ["Age"] = p.Age.ToString(),
        })
        .ToList();
xander
  • 1,689
  • 10
  • 18
  • I hope you don't mind the edit. I like your answer the best but the way it was laid out it was hard for me to read and I felt it lost visibility and hence votes. – Enigmativity Feb 16 '19 at 04:00
  • I'd also recommend including the source data to show that you can actually run your code and that it produces the correct result. – Enigmativity Feb 16 '19 at 04:02
  • Are you sure the dictionary constructor is used correctly? – Alexander Feb 16 '19 at 04:02
  • @Alexander - Yes, I ran and tested this code. It's using an alternative syntax. It's legal. – Enigmativity Feb 16 '19 at 04:08
  • 1
    @Alexander the dictionary initializer syntax [was introduced in C# 6.0](https://visualstudiomagazine.com/Blogs/Tool-Tracker/2015/04/C-Sharp-Dictionary-Initializers.aspx), which was released with Visual Studio 2015. It does require a modern enough tool set, but it works. – xander Feb 16 '19 at 04:21
  • @xander , thanks, I didn't know. I will use it! – Alexander Feb 16 '19 at 04:27
  • But this is very time consuming and for Millions of record it takes lot of time, is there any other process ? – Sampan Feb 17 '19 at 05:34