(Note: please see the edit...)
If you don't actually know beforehand whether you've got a string array or an array of arrays of strings, you'll need to conditionally call SelectMany
:
string[][] multi = words as string[][];
string[] flattened = multi == null ? words : multi.SelectMany(x => x).ToArray();
Note that in this case if you change the contents of flattened
, that will either change words
(if that was already flat) or just change a copy (if it was a jagged array). If you want to make it consistent, you could call words.ToArray()
in second operand of the conditional operator:
string[] flattened =
multi == null ? words.ToArray() : multi.SelectMany(x => x).ToArray();
Is there no way you can avoid the ambiguity to start with though? In particular, if you're in control over the LINQ to XML queries involved, you should be able to make them give a consistent result type.
EDIT: I've just realised that if you don't know the type of the data to start with, then words
is presumably declared as just object
or perhaps IEnumerable
. In that case, you'd want something like this:
public string[] Flatten(object words)
{
string[][] multi = words as string[][];
if (multi != null)
{
return multi.SelectMany(x => x).ToArray();
}
string[] single = words as string[];
if (single != null)
{
return single.ToArray(); // Defensive copy; remove if not needed
}
throw new ArgumentException("Argument must be string[] or string[][]");
}
This is still really icky - you should definitely try to make the queries give you some consistent result type instead.