using System;
using System.Collections;
using System.Collections.Generic;
class Program
{
static void Main(string[] args)
{
//Test with classes
string[] classesList1 = new[] {"a", "b", "c"};
string[] classesList2 = new[] { "1", "2", "3" };
List<string[]> classesListCombined = new List<string[]> { classesList1, classesList2 };
Console.WriteLine("classesList1: {0}", String.Join(",", classesList1.SelectManyRecusive<string>()));
Console.WriteLine("classesListCombined: {0}", String.Join(",", classesListCombined.SelectManyRecusive<string>()));
//Test with structs
int[] structList1 = new[] { 1, 2, 3 };
int[] structList2 = new[] { 4, 5, 6 };
List<int[]> structListCombined = new List<int[]> { structList1, structList2 };
Console.WriteLine("structList1: {0}", String.Join(",", structList1.SelectManyRecusive<int>()));
Console.WriteLine("structListCombined: {0}", String.Join(",", structListCombined.SelectManyRecusive<int>()));
//Test tripple nesting
var nest1 = new[] {1, 2, 3};
var nest2 = new[] { 4, 5, 6 };
var nest3 = new[] { 7, 8, 9 };
var nest4 = new[] {10, 11, 12};
var layer1 = new[] {nest1, nest2};
var layer2 = new[] {nest3, nest4};
var top = new[] {layer1, layer2};
Console.WriteLine("top: {0}", String.Join(",", top.SelectManyRecusive<int>()));
Console.ReadLine();
}
}
internal static class ExtensionMethods
{
public static IEnumerable<T> SelectManyRecusive<T>(this IEnumerable enumerable)
{
foreach (var item in enumerable)
{
var castEnumerable = item as IEnumerable;
if (castEnumerable != null
&& ((typeof(T) != typeof(string)) || !(castEnumerable is string))) //Don't split string to char if string is our target
{
foreach (var inner in SelectManyRecusive<T>(castEnumerable))
{
yield return inner;
}
}
else
{
if (item is T)
{
yield return (T) item;
}
}
}
}
}
dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uQ29sbGVjdGlvbnM7CnVzaW5nIFN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljOwoKICAgIGNsYXNzIFByb2dyYW0KICAgIHsKICAgICAgICBzdGF0aWMgdm9pZCBNYWluKHN0cmluZ1tdIGFyZ3MpCiAgICAgICAgewogICAgICAgICAgICAvL1Rlc3Qgd2l0aCBjbGFzc2VzCiAgICAgICAgICAgIHN0cmluZ1tdIGNsYXNzZXNMaXN0MSA9IG5ld1tdIHsiYSIsICJiIiwgImMifTsKICAgICAgICAgICAgc3RyaW5nW10gY2xhc3Nlc0xpc3QyID0gbmV3W10geyAiMSIsICIyIiwgIjMiIH07CiAgICAgICAgICAgIExpc3Q8c3RyaW5nW10+IGNsYXNzZXNMaXN0Q29tYmluZWQgPSBuZXcgTGlzdDxzdHJpbmdbXT4geyBjbGFzc2VzTGlzdDEsIGNsYXNzZXNMaXN0MiB9OwoKICAgICAgICAgICAgQ29uc29sZS5Xcml0ZUxpbmUoImNsYXNzZXNMaXN0MTogezB9IiwgU3RyaW5nLkpvaW4oIiwiLCBjbGFzc2VzTGlzdDEuU2VsZWN0TWFueVJlY3VzaXZlPHN0cmluZz4oKSkpOwogICAgICAgICAgICBDb25zb2xlLldyaXRlTGluZSgiY2xhc3Nlc0xpc3RDb21iaW5lZDogezB9IiwgU3RyaW5nLkpvaW4oIiwiLCBjbGFzc2VzTGlzdENvbWJpbmVkLlNlbGVjdE1hbnlSZWN1c2l2ZTxzdHJpbmc+KCkpKTsKCiAgICAgICAgICAgIC8vVGVzdCB3aXRoIHN0cnVjdHMKICAgICAgICAgICAgaW50W10gc3RydWN0TGlzdDEgPSBuZXdbXSB7IDEsIDIsIDMgfTsKICAgICAgICAgICAgaW50W10gc3RydWN0TGlzdDIgPSBuZXdbXSB7IDQsIDUsIDYgfTsKICAgICAgICAgICAgTGlzdDxpbnRbXT4gc3RydWN0TGlzdENvbWJpbmVkID0gbmV3IExpc3Q8aW50W10+IHsgc3RydWN0TGlzdDEsIHN0cnVjdExpc3QyIH07CgoKICAgICAgICAgICAgQ29uc29sZS5Xcml0ZUxpbmUoInN0cnVjdExpc3QxOiB7MH0iLCBTdHJpbmcuSm9pbigiLCIsIHN0cnVjdExpc3QxLlNlbGVjdE1hbnlSZWN1c2l2ZTxpbnQ+KCkpKTsKICAgICAgICAgICAgQ29uc29sZS5Xcml0ZUxpbmUoInN0cnVjdExpc3RDb21iaW5lZDogezB9IiwgU3RyaW5nLkpvaW4oIiwiLCBzdHJ1Y3RMaXN0Q29tYmluZWQuU2VsZWN0TWFueVJlY3VzaXZlPGludD4oKSkpOwoKICAgICAgICAgICAgLy9UZXN0IHRyaXBwbGUgbmVzdGluZwoKICAgICAgICAgICAgdmFyIG5lc3QxID0gbmV3W10gezEsIDIsIDN9OwogICAgICAgICAgICB2YXIgbmVzdDIgPSBuZXdbXSB7IDQsIDUsIDYgfTsKICAgICAgICAgICAgdmFyIG5lc3QzID0gbmV3W10geyA3LCA4LCA5IH07CiAgICAgICAgICAgIHZhciBuZXN0NCA9IG5ld1tdIHsxMCwgMTEsIDEyfTsKCiAgICAgICAgICAgIHZhciBsYXllcjEgPSBuZXdbXSB7bmVzdDEsIG5lc3QyfTsKICAgICAgICAgICAgdmFyIGxheWVyMiA9IG5ld1tdIHtuZXN0MywgbmVzdDR9OwogICAgICAgICAgICB2YXIgdG9wID0gbmV3W10ge2xheWVyMSwgbGF5ZXIyfTsKCgogICAgICAgICAgICBDb25zb2xlLldyaXRlTGluZSgidG9wOiB7MH0iLCBTdHJpbmcuSm9pbigiLCIsIHRvcC5TZWxlY3RNYW55UmVjdXNpdmU8aW50PigpKSk7CgogICAgICAgICAgICBDb25zb2xlLlJlYWRMaW5lKCk7CgogICAgICAgIH0KICAgIH0KCiAgICBpbnRlcm5hbCBzdGF0aWMgY2xhc3MgRXh0ZW5zaW9uTWV0aG9kcwogICAgewogICAgICAgIHB1YmxpYyBzdGF0aWMgSUVudW1lcmFibGU8VD4gU2VsZWN0TWFueVJlY3VzaXZlPFQ+KHRoaXMgSUVudW1lcmFibGUgZW51bWVyYWJsZSkKICAgICAgICB7CiAgICAgICAgICAgIGZvcmVhY2ggKHZhciBpdGVtIGluIGVudW1lcmFibGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhciBjYXN0RW51bWVyYWJsZSA9IGl0ZW0gYXMgSUVudW1lcmFibGU7CiAgICAgICAgICAgICAgICBpZiAoY2FzdEVudW1lcmFibGUgIT0gbnVsbCAKICAgICAgICAgICAgICAgICAgICAmJiAoKHR5cGVvZihUKSAhPSB0eXBlb2Yoc3RyaW5nKSkgfHwgIShjYXN0RW51bWVyYWJsZSBpcyBzdHJpbmcpKSkgLy9Eb24ndCBzcGxpdCBzdHJpbmcgdG8gY2hhciBpZiBzdHJpbmcgaXMgb3VyIHRhcmdldAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciBpbm5lciBpbiBTZWxlY3RNYW55UmVjdXNpdmU8VD4oY2FzdEVudW1lcmFibGUpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgeWllbGQgcmV0dXJuIGlubmVyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaXRlbSBpcyBUKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgeWllbGQgcmV0dXJuIChUKSBpdGVtOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0=
classesList1: a,b,c
classesListCombined: a,b,c,1,2,3
structList1: 1,2,3
structListCombined: 1,2,3,4,5,6
top: 1,2,3,4,5,6,7,8,9,10,11,12