Как преобразовать общую последовательность в треугольник с помощью 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.

Другие вопросы по тегам