tags:

views:

51

answers:

3

I have to dictionaries

dic1<double, double>
dic2<double, double>

The length might not match. So I need to update values in dic1 from dic2 joined by dic1.key == dic2.key... But preserve those values in dic1 which has no corresponding key in dic2.

.NET is 3.5

+3  A: 

You can just iterate over the values in dic2:

Dictionary<double, double> dic1;
Dictionary<double, double> dic2;
foreach (var pair in dic2)
{
    dic1[pair.Key] = pair.Value;
}

Or, if you want to update but not insert, check if the keys exist:

foreach (var pair in dic2)
{
    if (dic1.ContainsKey(pair.Key))
    {
        dic1[pair.Key] = pair.Value;
    }
}

Edit: If you really want to use Linq, you probably want to create a new dictionary rather than update an existing one:

dic1 =
    (from pair in dic1
     let Value = dic2.ContainsKey(pair.Key) ? dic2[pair.Key] : pair.Value
     select new { pair.Key, Value }
    ).ToDictionary(pair => pair.Key, pair => pair.Value);

or

dic1 =
    (from pair in dic1
     join pair2 in dic2 on pair.Key equals pair2.Key into g
     select new { pair.Key, g.DefaultIfEmpty(pair).First().Value }
    ).ToDictionary(pair => pair.Key, pair => pair.Value);

In my opinion that just makes it harder to read, though.

Quartermeister
If dic2 contains elements not in dic1, then you will add new elements.
Mikael Svenson
this is LINQ question.
Bobb
I did in foreach after all..
Bobb
Did a linq version myself, but removed the "select new" part. But I agree foreach is more readable. No need to linq something for the sake using linq.
Mikael Svenson
A: 

Try this:

var entries = dic2.Where(x => dic1.ContainsKey(x.Key));
foreach (KeyValuePair<double, double> entry in entries)
{
    dic1[entry.Key] = entry.Value;
}
ChrisBD
Ah - just too late - you've already accepted the previous post as an answer.
ChrisBD
+1  A: 

Here's a Linq outer left join version:

Dictionary<double, double> dictionary =
(from d1 in dic1
 join d2 in dic2 on d1.Key equals d2.Key into kvp
 from nv in kvp.DefaultIfEmpty(d1)
 select nv).ToDictionary(x => x.Key, x => x.Value);
Mikael Svenson
actually this works. but I decided to go with foreach after all.
Bobb
@Bobb Good choice :)
Mikael Svenson