patterncsharpMinor
Recursively find all objects of type System.Web.UI.Pair in an object array
Viewed 0 times
objectsallarraysystemrecursivelytypewebfindobjectpair
Problem
I have an object array that contains various types of objects (primitives, strings, other object arrays) at arbitrary levels of nesting. I need to pull all objects of type
A picture is worth a thousand words:
(Original URL: http://postimage.org/image/i7fuad3b9/)
Here's the method I came up with, but it feels inelegant and incomplete. Any improvements, especially ones that can leverage LINQ are welcome.
System.Web.UI.Pair from this array and am having a heck of a time writing the method. This is especially difficult because the Pair class itself can contain other Pairs or enumerable of Pairs. A picture is worth a thousand words:
(Original URL: http://postimage.org/image/i7fuad3b9/)
Here's the method I came up with, but it feels inelegant and incomplete. Any improvements, especially ones that can leverage LINQ are welcome.
public static IEnumerable Flatten(this object root, List list)
{
if (root == null)
{
return list;
}
if (root is Pair)
{
var pair = root as Pair;
list.Add(pair);
if (pair.First is IEnumerable)
{
Flatten((root as Pair).First, list);
}
else if (pair.First is Pair)
{
list.Add(pair.First as Pair);
}
if (pair.Second is IEnumerable)
{
Flatten((root as Pair).Second, list);
}
else if (pair.Second is Pair)
{
list.Add(pair.Second as Pair);
}
}
if (root.GetType().IsArray || root is IEnumerable)
{
foreach (object o in (IEnumerable) root)
{
Flatten(o, list);
}
}
return list;
}Solution
You might consider making this an extension method on
You can use it like this:
Or on an
Or on a regular
Pair instead of object. You could simplify it to this:public static IEnumerable Flatten(this Pair p, List toBuild = null)
{
if (toBuild == null)
toBuild = new List();
if (p.First is Pair)
{
(p.First as Pair).Flatten(toBuild);
}
else if (p.First is IEnumerable)
{
foreach (object o in (p.First as IEnumerable).OfType().Where(ob => ob is Pair))
{
(o as Pair).Flatten(toBuild);
}
}
//repeat for p.Second
toBuild.Add(p);
return toBuild;
}You can use it like this:
var result = myPair.Flatten();Or on an
IEnumerable:var result = myList.SelectMany(p => p.Flatten());Or on a regular
IEnumerable:var result = myList.OfType().Where(o => o is Pair)
.SelectMany(p => (p as Pair).Flatten());Code Snippets
public static IEnumerable<Pair> Flatten(this Pair p, List<Pair> toBuild = null)
{
if (toBuild == null)
toBuild = new List<Pair>();
if (p.First is Pair)
{
(p.First as Pair).Flatten(toBuild);
}
else if (p.First is IEnumerable)
{
foreach (object o in (p.First as IEnumerable).OfType<object>().Where(ob => ob is Pair))
{
(o as Pair).Flatten(toBuild);
}
}
//repeat for p.Second
toBuild.Add(p);
return toBuild;
}var result = myPair.Flatten();var result = myList.SelectMany(p => p.Flatten());var result = myList.OfType<object>().Where(o => o is Pair)
.SelectMany(p => (p as Pair).Flatten());Context
StackExchange Code Review Q#13513, answer score: 2
Revisions (0)
No revisions yet.