1

I am initialising a new Dictionary and putting each key one by one like so:

igData = data.Select(x => new Dictionary<string, string> { ["Date"] = x.GetValueOrDefault("DATE"), ["SP"] = x.GetValueOrDefault("SP"), ["IG"] = x.GetValueOrDefault("IG")}).ToList(); 

This is fine but the rest of the keys need to be headers that I have created in List<string> headers

Is it possible to add this list of headers within the initialisation above? Something like this:

igData = data.Select(x => new Dictionary<string, string> { ["Date"] = x.GetValueOrDefault("DATE"), ["SP"] = x.GetValueOrDefault("SP"), ["IG"] = x.GetValueOrDefault("IG"), headers.Select(y => new KeyValuePair<string, string> (y, x.GetValueOrDefault["IG"])).ToList(); 

I understand the value is the same but that is intended. Is the above possible or is this something I would have separate. It would be ideal to do it in the above since I have access to the value from the data collection.

8
  • What is the type of data/headers? Why do you create so many dictionaries? Commented Jun 17, 2019 at 9:59
  • 1
    You should use the ToDictionary extension. Commented Jun 17, 2019 at 9:59
  • @ChengChen data is a List<Dictionary<string, string>> and headers is List<string>. Commented Jun 17, 2019 at 9:59
  • If you want a list of KeyValuePair<string, string>, then use List<KeyValuePair<string, string>> instead of a dictionary. You then have an option of using AddRange() to add multiple items at one time where a dictionary only has Add(). Commented Jun 17, 2019 at 10:06
  • 2
    A collection of dictionaries allways make me feel like -uaaah, yeah - uncconfortable. They tend to grow unexpectably and thus become less and less maintanable, in particular when you data-structures become more complex. Instead you should consider to create a class with the properties. Commented Jun 17, 2019 at 10:09

4 Answers 4

3

You cant do it in an initializer like that, but I'd suggest you can do it with a little bit of Concat and ToDictionary:

igData = data.Select(x => { return new KeyValuePair<string,string>[]{ new KeyValuePair<string,string>("Date", x.GetValueOrDefault("DATE")), new KeyValuePair<string,string>("SP", x.GetValueOrDefault("SP")), new KeyValuePair<string,string>("IG", x.GetValueOrDefault("IG")) }.Concat( headers.GetHalfHourlyTimeHeaders().Select(y => new KeyValuePair<string, string> (y, x.GetValueOrDefault["IG"])).ToList() ).ToDictionary(k => k.Key, v => v.Value); }); 
Sign up to request clarification or add additional context in comments.

5 Comments

Is there a reason why you create an array of KVP instead of just initialising a new Dictionary and adding into that? Just trying to understand the code better.
Not really, just so I could chain (.Concat) them with your GetHalfHourlyTimeHeaders and create one dictionary.
Oh okay, so adding straight into a Dictionary would not work with Concat?
It probably would, A Dictionary is just an IEnumerable<KeyValuePair<>> - the question is, is the overhead of another dictionary necessary.
Okay, that makes sense. Thanks!
3
igData = data.Select(x => new Dictionary<string, string>(headers.GetHalfHourlyTimeHeaders().ToDictionary(y => y, y => x.GetValueOrDefault("IG"))) { ["Date"] = x.GetValueOrDefault("DATE"), ["SP"] = x.GetValueOrDefault("SP"), ["IG"] = x.GetValueOrDefault("IG") }); 

Query syntax looks better to me

igData = from x in data let ig = x.GetValueOrDefault("IG") select new Dictionary<string, string>(headers.GetHalfHourlyTimeHeaders().ToDictionary(y => y, y => ig)) { ["Date"] = x.GetValueOrDefault("DATE"), ["SP"] = x.GetValueOrDefault("SP"), ["IG"] = ig }; 

Comments

0

Similar to the answer of Jamiec but in my opinion more readable (but not tested for performance):

List<Dictionary<string, string>> igData = data.Select(x => { var dict = new Dictionary<string, string> { ["Date"] = x.GetValueOrDefault("DATE"), ["SP"] = x.GetValueOrDefault("SP"), ["IG"] = x.GetValueOrDefault("IG") }; // I hope I understand correctly that GetHalfHourlyTimeHeaders returns List<string> foreach (string header in headers.GetHalfHourlyTimeHeaders()) { dict.Add(header, x.GetValueOrDefault("IG")); } return dict; } ).ToList(); 

Comments

0

I like this way:

igData = data .Select(x => Enumerable .Concat( headers .GetHalfHourlyTimeHeaders() .Select(k => new { k, v = x.GetValueOrDefault("IG") }), new [] { "Date", "SP", "IG" } .Select(k => new { k, v = x.GetValueOrDefault(k.ToUpper()) })) .ToDictionary(z => z.k, z => z.v)) .ToList(); 

2 Comments

This doesn't work since it doesn't get the values from the data collection.
@UsmanKhan - Sorry, you're right. I missed that part of query. I've fixed it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.