在 C# 中比较和更新两个列表

发布于 2024-11-04 10:03:49 字数 546 浏览 0 评论 0原文

上下文是,我在内存中缓存了一组获取成本昂贵的值,以及另一组获取成本低廉且无法缓存的关联数据(业务规则)。我已经一切正常,但我只是想知道是否有人能想到一种更便宜的方式来进行此类更新......

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

它基本上只是将缓存的信息与我刚刚获得的信息进行匹配。这一切都有效,负载几乎可以忽略不计,但我有点追求效率。

编辑:在上面,searchItemsNonCached 和 searchItemsCached 都是 SearchItem 的列表,其中 Searchitem 是定制对象。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

内心旳酸楚 2024-11-11 10:03:49

将缓存的项目存储在字典中。现在,仅当密钥存在时才可以更新。

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

屌丝范 2024-11-11 10:03:49

加载带有缓存项的 Dictionary,然后循环遍历每个非缓存项以在字典中查找匹配项。这是 O(n),而不是 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;
  }
}

如果您可以考虑从一开始就使用 Dictionary 来缓存项目(而不是 List),那么您可以避免在查找匹配项之前加载它的步骤。

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.

ˇ宁静的妩媚 2024-11-11 10:03:49

您想要做的本质上是一个连接(在数据库意义上),特别是等连接。您可以查看维基百科文章的此部分有关连接算法的内容。您上面列出的代码是嵌套循环连接,adymitruk 的建议是哈希连接,但正如 Lou Franco 评论的那样,最好的方法可能取决于您的集合具有哪种排序或结构(如果有)。

如果 searchItemCached 只是一个无序列表,那么 哈希联接 可能是你最好的选择——只需从一个集合或另一个集合中构建一个字典,并以 ID 作为键,然后循环遍历另一个集合,从字典中查找匹配的项目。如果 searchItemCached 已经是一个按 ID 键控的字典,那么哈希联接绝对是您的最佳选择。如果 searchItemCachedsearchItemsNonCached 均按 ID 排序,则 sort-merge join 可能是正确的选择。

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.

浅沫记忆 2024-11-11 10:03:49

另一种方法是您可以编写一个 linq 表达式并连接 ID 上的两个列表,并使用更新的值创建相同类型的新对象。

前任

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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文