Есть массив object[]
элементы в свою очередь могут быть массивами ( т.е. всего м.б. не более 2 уровней вложенности )
Нужно развернуть исходный массив так чтобы получить всевозможные комбинации элементов вложенных массивов.
Поясню на примере , допустим исх. массив имеет 3 элемента
{ {a1} , {b1,b2}, {c1,c2,c3} }
На выходе нужно получить следующие массивы ( каждый из которых тоже будет иметь по 3 элемента )
Как это можно элегантно сделать. если размеры всех массивов заранее не известны ( т.е. все они object[] ) ?
Может как-то можно yield return задействовать ?
Re: Развернуть массив массивов
От:
Аноним
Дата:
29.06.08 07:21
Оценка:
Здравствуйте, astel, Вы писали:
A>Как это можно элегантно сделать. если размеры всех массивов заранее не известны ( т.е. все они object[] ) ?
А типы элемнтов вложенных массивов до приведения к object известны?
using System;
using System.Linq;
class Program
{
static object[][] Flat(object[][] array, int index)
{
if (index == array.Length - 1)
return array[index].Select(e => new[] { e }).ToArray();
return
(from e in array[index]
from i in Flat(array, index + 1)
select new[] { e }.Concat(i).ToArray()
).ToArray();
}
static object[][] Flat(object[][] array)
{
return Flat(array, 0);
}
static void Main(string[] args)
{
object[][] array = new[]{
new [] {"a1"},
new [] {"b1","b2"},
new [] {"c1","c2","c3"}
};
object[][] flat = Flat(array);
}
}
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, astel, Вы писали:
A>>Как это можно элегантно сделать. если размеры всех массивов заранее не известны ( т.е. все они object[] ) ?
А>А типы элемнтов вложенных массивов до приведения к object известны?
Не понял вопрос. На входе есть object[] ... это все что извеснто .... типы (если они нужны) можно на лету ведь узнать
Здравствуйте, Аноним, Вы писали:
А>Я немного не правильно сформулировал — на входе не object[][] , а object[]
Тогда вот так получится
using System;
using System.Linq;
using System.Collections.Generic;
class Program
{
static object[][] Flat(object[] array, int index)
{
var currentDimension =
array[index] is IEnumerable<object> ?
(IEnumerable<object>) array[index] :
new [] { array[index] };
if (index == array.Length - 1)
return currentDimension.Select(e => new[] { e }).ToArray();
return
(from e in currentDimension
from i in Flat(array, index + 1)
select new[] { e }.Concat(i).ToArray()
).ToArray();
}
static object[][] Flat(object[] array)
{
return Flat(array, 0);
}
static void Main(string[] args)
{
object[] array = new object[]{
"some object",
new [] {"b1","b2"},
new [] {"c1","c2","c3"},
"yet another object",
new [] {"d1","d2","d3","d4"}
};
object[][] flat = Flat(array);
}
}
Здравствуйте, astel, Вы писали:
A>Как это можно элегантно сделать. если размеры всех массивов заранее не известны ( т.е. все они object[] ) ? A>Может как-то можно yield return задействовать ?
static object[][] Zip(object[] data) {
var enumData = from d in data.OfType<IEnumerable>()
select d.OfType<object>();
var q = from line in Zip(enumData)
select line.ToArray();
return q.ToArray();
}
static IEnumerable<IEnumerable<T>> Zip<T>(IEnumerable<IEnumerable<T>> data) {
var q = from i in Enumerable.Range(0, int.MaxValue/2)
select Slice(data, i);
return q.TakeWhile(_ => _.Any());
}
static IEnumerable<T> Slice<T>(IEnumerable<IEnumerable<T>> data, int i) {
return from arr in data
where arr.Count() > i
select arr.ElementAt(i);
}