[英]yield return in the lambda expression?
下面的代码会将列表分成以“[”开头并以“]”结尾的子列表。 如何将其转换为使用yield return
以便它可以懒惰地处理非常庞大的流输入? -- 或者如何在 F# 中使用惰性枚举来实现它?--(没关系,我认为 f#implementation 应该是微不足道的)
var list = new List<string> { "[", "1", "2", "3", "]", "[", "2", "2", "]", "[", "3", "]" };
IEnumerable<IEnumerable<string>> result = Split(list);
static IEnumerable<IEnumerable<string>> Split(List<string> list)
{
return list.Aggregate(new List<List<string>>(), // yield return?
(sum, current) =>
{
if (current == "[")
sum.Add(new List<string>());
else if (current == "]")
return sum; // Convert to yield return?
else
sum.Last().Add(current);
return sum; // Convert to yield return?
});
}
C# 不支持匿名迭代器块,因此您只需使用命名方法而不是匿名方法。
public static IEnumerable<IEnumerable<string>> Split(IEnumerable<string> tokens)
{
using(var iterator = tokens.GetEnumerator())
while(iterator.MoveNext())
if(iterator.Current == "[")
yield return SplitGroup(iterator);
}
public static IEnumerable<string> SplitGroup(
IEnumerator<string> iterator)
{
while(iterator.MoveNext() && iterator.Current != "]")
yield return iterator.Current;
}
虽然 C# 不允许在 lambda 中yield
,但我认为我们可以像这样解决
static IEnumerable<IEnumerable<string>> Split(List<string> list)
{
var tmp = list as IEnumerable<string>;
while(tmp.FirstOrDefault() == "[")
{
yield return tmp.TakeWhile((current) => current != "]");
tmp = tmp.SkipWhile((current) => current != "]");
}
}
您的任务最简单的解决方案是这种方法:
IEnumerable<IEnumerable<string>> SplitList(IEnumerable<string> list, string open = @"[", string close = @"]") {
Dictionary<int, List<string>> splitedList = new Dictionary<int, List<string>>();
int i = 0;
foreach (var s in list) {
if (open.Equals(s))
splitedList.Add(i, new List<string>());
else if (close.Equals(s))
i++;
else
splitedList[i].Add(s);
}
return splitedList.Values;
}
我找到了另一种方法,使用Linq
。 不确定效率,但它有效。
int index=0;
list.Select(item=> new { item=item, index= item=="]"? ++index : index })
.Where(c => !(c.item == "[" || c.item =="]"))
.GroupBy(g=>g.index)
.Select(e=> e.Select(c=>c.item));
工作Demo
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.