如何直接返回ILookup(不使用Dictionary-> ILookup转换器)

时间:2013-11-29 17:51:36

标签: c# linq dictionary lookup yield-return

(将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

1 个答案:

答案 0 :(得分:4)

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

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

它不符合ILookup<Type, Entry>界面,但你提供的代码也没有,所以我无法确定你真正想要的是什么。

重新阅读问题之后的尝试:

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}; 
}