Csharp/C#教程:是否可以实现递归“SelectMany”?分享


是否可以实现递归“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 s = new List { "1", new string[] {"2","3"}, "4", new object[] {new string[] {"5","6"},new string[] {"7","8"},}, }; var fs = Flatten(s); foreach (string str in fs) Console.WriteLine(str); Console.ReadLine(); 

显然,它确实缺少一些类型有效性检查( InvalidCastExcpetion如果集合不包含T ,可能还有一些其他缺点)……好吧,至少它是懒惰评估的,如期望的那样。

添加了!(o is T)以防止stringchar数组

上述就是C#学习教程:是否可以实现递归“SelectMany”?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/1012386.html

(0)
上一篇 2021年12月30日
下一篇 2021年12月30日

精彩推荐