是否可以实现递归“SelectMany”?
众所周知, Enumerable.SelectMany
将一系列序列展平为单个序列。 如果我们想要一种能够使序列序列序列变平,等等递归的方法怎么办?
我很快就得到了一个使用ICollection
,即热切评估,但我仍然在考虑如何使用yield
关键字制作一个懒惰评估的实现。
static List Flatten(IEnumerable list) { var rv = new List(); InnerFlatten(list, rv); return rv; } static void InnerFlatten(IEnumerable list, ICollection acc) { foreach (var elem in list) { var collection = elem as IEnumerable; if (collection != null) { InnerFlatten(collection, acc); } else { acc.Add((T)elem); } } }
有任何想法吗? 任何.NET语言欢迎中的示例。
这在F#中具有递归序列表达式是微不足道的。
let rec flatten (items: IEnumerable) = seq { for x in items do match x with | :? 'T as v -> yield v | :? IEnumerable as e -> yield! flatten e | _ -> failwithf "Expected IEnumerable or %A" typeof<'T> }
一个测试:
// forces 'T list to obj list let (!) (l: obj list) = l let y = ![["1";"2"];"3";[!["4";["5"];["6"]];["7"]];"8"] let z : string list = flatten y |> Seq.toList // val z : string list = ["1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"]
据我了解你的想法,这是我的变种:
static IEnumerable Flatten (IEnumerable collection) { foreach (var o in collection) { if (o is IEnumerable && !(o is T)) { foreach (T t in Flatten ((IEnumerable)o)) yield return t; } else yield return (T)o; } }
并检查它
List
显然,它确实缺少一些类型有效性检查( InvalidCastExcpetion
如果集合不包含T
,可能还有一些其他缺点)……好吧,至少它是懒惰评估的,如期望的那样。
添加了!(o is T)
以防止string
为char
数组
上述就是C#学习教程:是否可以实现递归“SelectMany”?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1012386.html