R/W csv with dynamic size of columns to a lookup table by CSVHelper

Viewed 44

I have a csv data like this

Header1 Header2 Header3 ... ValueN
Key1 Value11 Value12 Value13 ... Value1N
Key2 Value21 Value22 Value23 ... Value2N
Key3 Value31 Value32 Value33 ... Value3N
... ... ... ... ... ...
KeyN ValueN1 ValueN2 ValueN3 ... ValueNN

which have dynamic size of columns.
I want to load it to a lookup table

dictionary<string, dictionary<string, string>> lookup_table

so I can get data by

data = lookup_table[key_name][header_name] 

Furthermore, I have to write back to csv if data got changed. How should I create my class and map to read/write it?
csvhelper version = 28.0.1

1 Answers

Except for @dbc comment that the order of the items may change due to the unordered nature of Dictionary<TKey, TValue>, this should work.

void Main()
{
    var lookup_table = new Dictionary<string, Dictionary<string, string>>();
    
    using (var reader = new StringReader(",Header1,Header2,Header3\nKey1,value11,value12,value13\nKey2,value21,value22,value23"))
    using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
    {       
        csv.Read();
        csv.ReadHeader();
        
        var headerLength = csv.Context.Reader.HeaderRecord.Length;
        var header = csv.Context.Reader.HeaderRecord;
        
        while (csv.Read())
        {
            var key = csv.GetField(0);
            lookup_table.Add(key, new Dictionary<string, string>());
            
            for (int i = 1; i < headerLength; i++)
            {
                lookup_table[key][header[i]] = csv.GetField(i);
            }
        }
    }
    
    using (var csv = new CsvWriter(Console.Out, CultureInfo.InvariantCulture))
    {
        var headers = lookup_table.First().Value.Keys.ToList();
        
        csv.WriteField(string.Empty);
        
        foreach (var header in headers)
        {
            csv.WriteField(header);
        }
        
        csv.NextRecord();
        
        foreach (KeyValuePair<string, Dictionary<string, string>> entry in lookup_table)
        {
            csv.WriteField(entry.Key);
            
            for (int i = 0; i < headers.Count; i++)
            {
                csv.WriteField(entry.Value[headers[i]]);
            }
            
            csv.NextRecord();
        }
    }
}
Related