2017-05-09 40 views
1

如果我有一个序列IEnumerable<T>(不是数字,只是T):如何使用LINQ将通用序列转换为三角形?

[ a, b, c, d ] 

如何返回排序帕斯卡或Floyd的三角:

a 
ab 
abc 
abcd 

所以这将是IEnumerable<IEnumerable<T>>

想知道是否有一种方法来实现这一点,使用LINQ而不是手动使用循环实现。

回答

1

这应该工作:

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()); 
+0

这很可爱!你可能想提一个假设,序列的元素需要是唯一的。 – dasblinkenlight

+1

'Select((x,i)=> ...)'会以更有效的方式来做同样的技巧吗? – abatishchev

+0

是的,你是对的。 – Etienne

1

代替for环的使用Enumerable.Range让你建立与一个单一的代码线的三角形:

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.

+0

问正确的问题是解决方案的一半:)我得到了同样的结果,但为了避免双重序列枚举必须要求'IReadOnlyCollection '事先知道它的长度。想知道是否有办法接受'IEnumerable ',但仍只列举一次。 – abatishchev

+0

假设长度= 4的任意序列,我不认为它是一个有效的帕斯卡或弗洛伊德的三角形。 – Romoku

+0

@Romoku:我不是在寻找有效的帕斯卡尔或弗洛伊德的三角形,只是没有找到更好的方式来解释我在找什么。基本上只是一个三角形。 – abatishchev

2

这里有一个方法:

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(); 
} 

(A字符串是字符数组。)

ħ

赫尔
地狱
你好
你好,
您好,
您好,瓦特
你好,我
你好,wor
你好,worl
你好,世界
你好,世界!

+0

希望你不会介意给Etienne一些额外的分数,因为他/她的解决方案比你初次发布时略微早一些。 – abatishchev

相关问题