Mikey Hogarth
Mikey Hogarth

Reputation: 4702

compare and update two lists in C#

The context is that I have one cached set of values in memory that were expensive to fetch, and another set of associated data that is inexpensive to fetch and can't be cached (business rule). I've got it all working but I was just wondering if anyone could think of a less expensive way of doing this sort of update...

    foreach (var nonCachedItem in searchItemsNonCached)
    {
        foreach (var cachedItem in searchItemsCached)
        {
            if (cachedItem.ID == nonCachedItem.ID)
                nonCachedItem.Description = cachedItem.Description;
        }
    }

it's basically just to match up the cached information with the information I just got. It all works and the load is almost negligable but I'm kind of a sucker for efficiency.

EDIT: in the above, searchItemsNonCached and searchItemsCached are both Lists of SearchItem where Searchitem is a bespoke object.

Upvotes: 4

Views: 3465

Answers (4)

Brian Gideon
Brian Gideon

Reputation: 48949

Load a Dictionary with the cached items and then cycle through each non-cached item looking for a match in the dictionary. This is O(n) as opposed to the nested loop which is O(n^2).

var cachedDictionary = new Dictionary<int, YourType>();
foreach (var item in searchItemsCached)
{
  cachedDictionary.Add(item.ID, item);
}
foreach (var item in searchItemsNonCached)
{
  YourType match;
  if (cachedDictionary.TryGetValue(out match))
  {
    item.Description = match.Description;
  }
}

If you could consider using a Dictionary for the cached items from the beginning (instead of a List) then you could avoid the step of loading it before finding matches.

Upvotes: 3

Aaron
Aaron

Reputation: 2013

What you're trying to do is essentially a join (in the database sense), specifically an equi-join. You might check out this section of a Wikipedia article on join algorithms. The code you listed above is a nested-loop join, and adymitruk's suggestion is a hash join, but as Lou Franco commented, the best approach probably depends on what kind of ordering or structure (if any) your collections have.

If searchItemCached is just an unordered list, then a hash join is probably your best bet--just build a dictionary from one collection or the other with the ID as the key, then loop through the other collection looking up the matching items from the dictionary. If searchItemCached is already a dictionary keyed by ID, then a hash join is definitely your best bet. If searchItemCached and searchItemsNonCached are both sorted by ID, then a sort-merge join is probably the way to go.

Upvotes: 0

AD.Net
AD.Net

Reputation: 13399

Another approach is you can write a linq expression and join the two lists on ID, and create new objects of same type with updated values.

ex

from nc in searchItemsNonCached
join c in searchItemCached on nc.ID equals c.ID
select new (same type) // and assign the desc from c.Description

Upvotes: -1

Adam Dymitruk
Adam Dymitruk

Reputation: 129564

Store your cached items in a dictionary. Now you can update only if the key exists.

Upvotes: 5

Related Questions