Mohammad Dayyan
Mohammad Dayyan

Reputation: 22458

Access to an array items?

I have a variable that contains :
Sometimes array of strings and sometimes array of array of strings
e.g:

var words = a LINQ to XML query;
//words == { "01", "02", "03", ... }
//or
//words == { {"01", "02", "03"}, {"04", "05", "06"}, ... }

Now , I wanna access to each item in the words array with a for statement
Could you please guide me ?
Thanks

Upvotes: 3

Views: 504

Answers (2)

Jon Skeet
Jon Skeet

Reputation: 1503270

(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.

Upvotes: 3

Mark Byers
Mark Byers

Reputation: 839044

You can convert the second form to the first using SelectMany:

string[] words = words2.SelectMany(x => x).ToArray();

Upvotes: 2

Related Questions