代码之家  ›  专栏  ›  技术社区  ›  Brian Berns

Linq-将一个ILookup转换为另一个ILookup

  •  1
  • Brian Berns  · 技术社区  · 15 年前

    这应该很简单,但我想不出一个好办法来做。如何将一个ILookup转换为另一个ILookup?例如,如何复制/克隆一个ILookup,生成另一个具有相同密钥和相同组的ILookup?

    static ILookup<TKey, TValue> Copy<TKey, TValue>(ILookup<TKey, TValue> lookup)
    {
        return lookup
            .ToDictionary(
                grouping => grouping.Key,
                grouping => grouping.ToArray())
            .SelectMany(pair =>
                pair
                    .Value
                    .Select(value =>
                        new KeyValuePair<TKey, TValue>(pair.Key, value)))
            .ToLookup(pair => pair.Key, pair => pair.Value);
    }
    

    有人能改进吗?

    2 回复  |  直到 15 年前
        1
  •  1
  •   Gabe Timothy Khouri    15 年前

    这是你想要的吗?

    static ILookup<TKey, TValue> Copy<TKey, TValue>(ILookup<TKey, TValue> lookup)
    {
        return lookup.
               SelectMany(g => g,
                         (g, v) => new KeyValuePair<TKey, TValue>(g.Key, v)).
               ToLookup(kvp => kvp.Key, kvp => kvp.Value);
    }
    

    当然,如果你想以某种方式转换这些值,也许你想要这样的东西:

    static ILookup<TKey, TValueOut> Transform<TKey, TValue, TValueOut>(
           ILookup<TKey, TValue> lookup,
           Func<TValue, TValueOut> selector)
    {
        return lookup.
               SelectMany(g => g,
                          (g, v) => new KeyValuePair<TKey, TValueOut>(g.Key, selector(v))).
               ToLookup(kvp => kvp.Key, kvp => kvp.Value);
    }
    

    KeyValuePair 它是一种值类型,存储在堆栈上,因此不需要任何中间内存分配。我分析了一个创建 Lookup<int,int> 有100个密钥,每个密钥有10000个项目(总共1000000个)。

    • Lookup 执行1610个分配。
    • 用我的方法复制它可以进行1712次分配(创建它所需的所有分配,以及 SelectMany 为每个键调用一个枚举器)。
    • 用匿名对象复制而不是 执行1001712分配(复制所需的所有分配加上每个项目的一个分配)。

    CPU方面,即使在 查找 两种复制方法的性能相同。每个键有1000000个元素,这两种方法的性能不同:

    • 5.1秒创建
    • 键值对
    • 使用匿名对象复制的时间为6.3秒
        2
  •  4
  •   Joe Albahari    15 年前

    return lookup
      .SelectMany (grp => grp, (grp, item) => new { grp.Key, item})
      .ToLookup (x => x.Key, x => x.item);
    
    推荐文章