Reputation: 2037
I have two lists of the following class:
public class KeyValues
{
public int Key { get;set;}
public List<double> DoubleList { get;set;}
}
var list1 = new List<KeyValues>();
list1.Add (new KeyValues(){Key = 33, DoubleList = new List<double>(){2.3,2.4,2.5}});
list1.Add (new KeyValues(){Key = 34, DoubleList = new List<double>(){3.3,3.4,3.5}});
list1.Add (new KeyValues(){Key = 35, DoubleList = new List<double>(){4.3,4.4,4.5}});
var list2 = new List<KeyValues>();
list2.Add (new KeyValues(){Key = 33, DoubleList = new List<double>(){20.3,20.4}});
list2.Add (new KeyValues(){Key = 34, DoubleList = new List<double>(){30.3,30.4}});
list2.Add (new KeyValues(){Key = 35, DoubleList = new List<double>(){40.3,40.4}});
I would like to combine those into a new list by mathing the keys and combining the sub lists. So the result should be:
list3 = [
[33, {2.3,2.4,2.5,20.3,20.4}]
[34, {3.3,3.4,3.5,30.3,30.4}]
[35, {4.3,4.4,4.5,40.3,40.4}]
]
Of course I can iterate over the keys, but isn't there a much better (faster) linq solution for this?
Upvotes: 1
Views: 2884
Reputation: 8360
My first suggestion here is to use Dicitionary<int, List<double>>
instead of creating a class KeyValues
or if you want specifically to use Key-Value pair, then .net have that too, it's called: KeyValuePair
.
Just in case if you are interested, here is the way to convert your class to Dictionary
:
var list3 = list1.Concat(list2)
.ToDictionary(item => item.Key);
Note: this will actually fail because of key duplications, so in case if you don't want that to happen, make sure that Key
s are different.
Update:
Or you can use Lookup<TKey, TElement>
to make it work even with duplicate keys:
var list3 = list1
.Concat(list2)
.ToLookup(group => group.Key, group => group.DoubleList)
.ToDictionary(group => group.Key, group => group.First());
One suggestion: you can use a collection initializer instead of adding elements one by one:
var list1 = new List<KeyValues>
{
new KeyValues {Key = 33, DoubleList = new List<double>() {2.3, 2.4, 2.5}},
new KeyValues {Key = 34, DoubleList = new List<double>() {3.3, 3.4, 3.5}},
new KeyValues {Key = 35, DoubleList = new List<double>() {4.3, 4.4, 4.5}}
};
More information:
Upvotes: 1
Reputation: 23298
Using Concat
and GroupBy
methods can produce the expected result (after making a code compile, of course)
var result = list1.Concat(list2).GroupBy(kv => kv.Key, kv => kv.DoubleList)
.Select(g => new KeyValues { Key = g.Key, DoubleList = g.SelectMany(i => i).ToList() });
Upvotes: 3
Reputation: 1322
You're example is not syntactically correct: Should be like this:
var list1 = new List<KeyValue>();
list1.Add(new KeyValue { Key = 33, DoubleList = new List<double>() { 2.3, 2.4, 2.5 } });
list1.Add(new KeyValue { Key = 34, DoubleList = new List<double>() { 3.3, 3.4, 3.5 } });
list1.Add(new KeyValue { Key = 35, DoubleList = new List<double>() { 4.3, 4.4, 4.5 } });
var list2 = new List<KeyValue>();
list2.Add(new KeyValue { Key = 33, DoubleList = new List<double>() { 20.3, 20.4 } });
list2.Add(new KeyValue { Key = 34, DoubleList = new List<double>() { 30.3, 30.4 } });
list2.Add(new KeyValue { Key = 35, DoubleList = new List<double>() { 40.3, 40.4 } });
list1.Zip(list2, (first, second) => (first.Key, first.DoubleList.Concat(second.DoubleList));
If the lists have the same element keys in the same order you can do this:
list1.Zip(list2, (first, second) =>
(first.Key, first.DoubleList.Concat(second.DoubleList)));
Upvotes: 1
Reputation: 119186
You can concatenate the two lists together and then use GroupBy
, and then Select
to project the output into the desired format. For example:
var list3 = list1.Concat(list2)
.GroupBy(x => x.Key)
.Select(x => new KeyValue
{
Key = x.Key,
DoubleList = x.SelectMany(x => x.DoubleList).ToList()
})
.ToList();
Upvotes: 1