【问题标题】:How to return ILookup directly (without using a Dictionary->ILookup converter)如何直接返回 ILookup(不使用 Dictionary->ILookup 转换器)
【发布时间】:2013-11-29 17:51:35
【问题描述】:

(将Dictionary 转换为ILookup 不是很好: How do I convert a Dictionary to a Lookup?)

我想使用以下方法为我的容器类创建一个接口:

ILookup<Type, Entry> Query ( IEnumerable<QueryClause> query );

每个查询子句都指定应从底层容器中取出哪些特殊类型的条目以及应取出多少(以及更多细节)。

我的实现目前看起来像这样:

var result = new Dictionary<Type, List<Entry>>();

foreach(var clause in query)
{
    var clauseResult = FulfillClause(clause);
    result.Add(clause.Type, clauseResult);
}

return result.ToLookup(); // here it is

这个方法有没有机会我直接返回ILookup?不幸的是它不支持yield return

【问题讨论】:

  • 您的代码似乎没有使用yield return,因此很难看出这有什么关系……而且您还没有告诉我们任何有关queryFulfillClause 的信息。
  • 我想替换结果。但是,添加行与收益返回,这是不可能的,因为 C# 不支持 ILookup 的收益返回(仅 IEnumerable)

标签: c# linq dictionary lookup yield-return


【解决方案1】:

我不完全确定您为什么首先拥有字典。这对你有用吗?

return query.ToLookup(clause => clause.Type, clause => FullFillClause(clause));

它不符合ILookup&lt;Type, Entry&gt; 接口,但你提供的代码也不符合,所以我无法确定你真正想要什么。

重新阅读问题后的尝试:

return query.SelectMany(c => FulfillClause(c).Select(r => new {Type=c.Type, Result=r}))
            .ToLookup(o => o.Type, o => o.Result);

这是@JonSkeet 的链接答案的翻译。

为了在不知道所有类型和方法的细节的情况下进行测试,我使用了这个:

Func<List<int>> f = () => new List<int>() {1, 2, 3};
var query = new List<Type> {typeof (int), typeof (string)};

var l = query.SelectMany(t => f().Select(n => new {Type = t, Result = n}))
    .ToLookup(o => o.Type, o => o.Result);

如果你控制了所有的代码,你可以重组其中的一些来提高可读性:

return query.SelectMany(c => c.Fulfill())
            .ToLookup(res => res.Type, res => res.Value);

...
// You will need to create the ClauseFulfillment type yourself
public IEnumerable<ClauseFulfillment> FulFill()
{
   var results = // whatever FulfillClause does
   foreach(var r in results)
      yield return new ClauseFulfillment {Type = Type, Result = r}; 
}

【讨论】:

  • 为什么我的代码不符合 ILookup 接口?给定链接线程中给出的字典和 ToLookup 扩展方法,我实现了接口。
  • 请看一下链接的帖子,谢谢。它显示了一个扩展方法,它将 Dictionary> 转换为 Lookup.
  • 感谢您的大力支持! +1!但是,我不太确定新代码是否真的比我原来的工作更具可读性。还是谢谢你。我希望 C# 允许我做一些收益回报的事情 :-)
  • @D.R. - 不客气!如果你控制了所有代码,我已经更新了我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多