说到Linq-one-liners)
一般来说,有这样一个任务:
有IEnumerable<string>一个包含一些行。还有int[],它包含上述集合中应插入空行的位置
例子:
// IEnumerable<string> collection:
"Some"
"Strings"
"To"
"Test"
"Method"
// int[] mask:
1
2
4
// IEnumerable<string> result:
"Some"
""
""
"Strings"
""
"To"
"Test"
"Method"
美妙之Linq处在于在没有任何额外变量和显式循环的情况下转换集合。但是,如果不引入一个新的变量,我就无法解决这个问题,所以我想问你:哪个解决方案会更优雅?)
我的实现:
脑袋上:
int i = 0;
List<string> result = new List<string>();
foreach (string x in collection)
{
while (mask.Contains(i))
{
result.Add(string.Empty);
++i;
}
result.Add(x);
++i;
}
相同,但有 SelectMany:
int i = 0;
IEnumerable<string> result = collection.SelectMany(x => {
List<string> part = new List<string>();
while (mask.Contains(i))
{
part.Add(string.Empty);
++i;
}
part.Add(x);
++i;
return part; });
升级版:
这在这类任务中通常很重要,所以我澄清一下:它mask是一个有序数组
实际上,@VladD给出了一个好主意:
实际上,如果我们从每个第 0
i个元素中减去maskN 0 i ( N 0是一个非负整数序列),我们将得到一个预先计算好的位置集合,其中必须插入空字符串简单地说,我们只需
mask要从每个元素中减去它在数组中的位置收到需要插入空行的位置集合后,我们已经使用了相同的
SelectMany最终代码:
结果:
事实上,我们得到了我们所期望的)
再次感谢您的好主意!
与预处理相同的想法的另一个变体。
让我们创建一个字典:
有了这个,我们得到一个这样的查询:
当掩码的索引为 0 时,需要第一行。