[ACCEPTED]-When using a LINQ Where clause on a Dictionary, how can I return a dictionary of the same type?-optimization
Pretty sure you could just call ToDictionary 1 on the result of the Where call:
Dictionary<string, string> GetValidIds(Dictionary<string, string> salesPersons,
IList<string> ids)
{
return salesPersons
.Where(p => ids.Contains(p.Key))
.ToDictionary(p => p.Key, p => p.Value);
}
Interestingly, if you enumerate over the 18 dictionary (length N) first and check the list 17 (length M) for inclusion, then you get O(NM) performance.
You 16 could build a HashSet<>
of the ids, but that seems 15 redundant since we already have a (pre-hashed) dictionary 14 available.
I would instead iterate over the 13 ids first; since dictionary lookup (by key) is 12 O(1), this gives O(M) performance - this 11 might, however, mean that you don't use 10 LINQ (since TryGetValue
won't love LINQ (and introducing 9 a tuple is too much like hard work)...
Dictionary<string, string> getValidIds(
IDictionary<string, string> salesPersons,
IEnumerable<string> ids) {
var result = new Dictionary<string, string>();
string value;
foreach (string key in ids) {
if (salesPersons.TryGetValue(key, out value)) {
result.Add(key, value);
}
}
return result;
}
It 8 doesn't overly concern me that this is more 7 lines than the LINQ version; it removes 6 an O(N) of complexity...
Edit; the following 5 might work (I haven't tested it), but I think 4 it is an abuse of LINQ, and certainly won't 3 scale to PLINQ etc... use with extreme caution!! I 2 also believe the foreach
approach simply has fewer 1 overheads, so will be quicker... anyway:
Dictionary<string, string> getValidIds(
IDictionary<string, string> salesPersons,
IEnumerable<string> ids)
{
string value = null;
return (from key in ids
where salesPersons.TryGetValue(key, out value) // HACK: v. dodgy
select new { key, value })
.ToDictionary(x=>x.key, x=>x.value);
}
Seems to be a lot of fussing about looking 5 things up in the List. If the list only 4 contains a few elements, then no big deal. If 3 the List contains thousands of elements, you're 2 going to want O(1) lookups into it. HashSet 1 can provide this.
Dictionary<string, string> getValidIds(
Dictionary<string, string> SalesPersons,
List<string> ids
)
{
HashSet<string> idsFast = new HashSet<string>(ids);
Dictionary<string, string> result = SalesPersons
.Where(kvp => idsFast.Contains(kvp.Key))
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value)
return result;
}
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.