配列の配列をフラット化するにはどうすればよいですか?

最初のステップでは、データを 1 種類のタイプに正規化する必要があります。その後、好きなようにそれらを繰り返すことができます。最初に、特定のポイントから任意の深さまで値を平坦化するメソッドを作成します:

public static class Extensions
{
    public static IEnumerable<object> FlattenArrays(this IEnumerable source)
    {
        foreach (var item in source)
        {
            if (item is IEnumerable inner
                && !(item is string))
            {
                foreach (var innerItem in inner.FlattenArrays())
                {
                    yield return innerItem;
                }
            }

            yield return item;
        }
    }
}

これで、トップ レベルで反復処理を行って、すべての値の 1 つの配列を取得できます。

// Produces one array => ["1", "2", "3", "4", ...]
var allFlat = schools.FlattenArrays().OfType<string>().ToArray();

または、個々の配列を 1 つ深く作成することもできます:

foreach (var item in schools)
{
    // Produces an array for each top level e.g. ["5", "6", "7", "8"]
    var flat = item.FlattenArrays().OfType<string>().ToArray();
}

コメントによると、内部配列に string[] の要素が混在しているためです と string 、Linq で直接これを行うのは簡単ではないでしょう。

ただし、ヘルパー関数の助けを借りて (私は Flattener を呼び出しました) ) 両方の内部型の処理を手動で分岐して、配列内の要素を返すことができます (string[] の場合) )、またはそうでない場合は、単一の要素を列挙可能として返します。 SelectMany その後、内側のレベルを平坦化するために使用できますが、外側のレベルは平坦化しないままにしておきたいようです:

つまり

var schools = new [] {
    new object[]{new[]{"1","2"}, "3","4"}, 
    new object[]{new[]{"5","6"}, "7","8"},
    new object[]{new[]{"9","10","11"}, "12","13"}
};

var result = schools
    .Select(s => s.SelectMany(o => Flattener(o)));

IEnumerable<IEnumerable<string>> の型を返します

厄介なアンパック ビットが行われた場所:

public IEnumerable<string> Flattener(object o)
{
    if (o is IEnumerable<string> strings)
    {
        return strings;
    }
    if (o is string s)
    {
       return new[]{s};
    }
    return new[]{"?"};
}

上記は C#7 のパターン マッチング機能を使用していることに注意してください。

結果のスクリーンショットは LinqPad 提供:


No