遍历异构容器?

  • 本文关键字:异构 遍历 c# linq
  • 更新时间 :
  • 英文 :


我正在尝试迭代一个简单的异构容器:Dictionary<string, object>.

它是这样构造的:

var d = new Dictionary<string, object>();
d.Add("key1", "value1");
d.Add("key2", 42);
var sub = new Dictionary<string, object>();
sub.Add("key3", new double[] { 0, 0 });
d.Add("key4", sub);

我假设我可以写一个简单的函数:

public IEnumerable<KeyValuePair<string, object>> flatten(IDictionary<string, object> dict)
{
foreach(KeyValuePair<string, object> item in dict)
{
if (item.Value is IDictionary<string, object> subDict)
{
flatten(subDict);
}
else
{
yield return item;
}
}
}

我如何重写上面的flatten函数,使:

var l = flatten(d).ToList();

返回一个包含三个项目的列表(键为:key1、key2和key3)。我还没有能够使用SelectMany从Linq包在我的情况下到目前为止…

Try yield returnflatten递归调用的结果:

public IEnumerable<KeyValuePair<string, object>> flatten(IDictionary<string, object> dict)
{
foreach (KeyValuePair<string, object> item in dict)
{
if (item.Value is IDictionary<string, object> subDict)
{
foreach (var item2 in flatten(subDict))
{
yield return item2;
}
}
else
{
yield return item;
}
}
}

如果您想使用SelectMany,您实际上需要将非IDictionary<...>投影到IEnumerable(因此dict总是被认为是要扁平的集合的集合):

public IEnumerable<KeyValuePair<string, object>> flatten(IDictionary<string, object> dict)
{
return dict.SelectMany(kv => kv.Value switch {
IDictionary<string, object> subdict => flatten(subdict),
_ => Enumerable.Repeat(kv, 1)
});
}

现场演示

我们不需要说yield return因为SelectMany会直接返回IEnumerable

最新更新