Как преобразовать общую последовательность в треугольник с помощью LINQ?
Если у меня есть последовательность IEnumerable<T>
(не цифры, просто T
):
[ a, b, c, d ]
Как вернуть сортировку треугольника Паскаля или Флойда:
a
ab
abc
abcd
так было бы IEnumerable<IEnumerable<T>>
?
Хотите знать, есть ли способ достичь этого элегантно с помощью LINQ, а не реализовать вручную с помощью циклов.
3 ответа
Решение
Это должно работать:
var seq = new List<string> { "a", "b", "c", "d" };
var pascal = seq.Select(a => seq.Take(seq.IndexOf(a) +1 ).ToList());
редактировать:
var seq = new List<string> { "a", "b", "c", "d" };
var pascal = seq.Select((a,i) => seq.Take(i+1).ToList());
Вот метод:
T[][] ToTriangle<T>(IEnumerable<T> input)
{
var inputAsList = input as List<T> ?? input.ToList();
return inputAsList.Select((t, i) => inputAsList.Take(i + 1).ToArray()).ToArray();
}
Из консольного приложения:
static void Main(string[] args)
{
var input = "Hello, world!";
var output = ToTriangle(input);
foreach (var set in output)
{
Console.WriteLine(string.Join("",set));
}
Console.ReadLine();
}
(Строка - это массив символов.)
ЧАС
Он
высокоэнергетический лазер
Ад
Привет
Привет,
Привет,
Привет
Привет
Привет
Привет, мир
Привет, мир
Привет, мир!
С помощью Enumerable.Range
на месте for
Цикл позволяет построить треугольник с одной строкой кода:
var data = new string[] {"a", "b", "c", "d"};
var triangle = Enumerable.Range(1, data.Length).Select(row => data.Take(row));
Enumerable.Range
служит внешней петлей; data.Take(row)
служит внутренней петлей.
Demo.