C# 是否有更简洁的Linq表达式用于在列表中的每个项之间插入常量?
以下是我目前的情况:C# 是否有更简洁的Linq表达式用于在列表中的每个项之间插入常量?,c#,linq,C#,Linq,以下是我目前的情况: public List<double> GetStrokeDashArray(List<double> dashLengths, double gap) { return dashLengths .SelectMany(dl => new[] { dl, gap }) .Take(dashLengths.Count * 2 - 1) .ToList(); } 您可以改用迭代器块: IEn
public List<double> GetStrokeDashArray(List<double> dashLengths, double gap)
{
return dashLengths
.SelectMany(dl => new[] { dl, gap })
.Take(dashLengths.Count * 2 - 1)
.ToList();
}
您可以改用迭代器块:
IEnumerable<Double> GetStrokeDashArray(IEnumerable<Double> dashLengths, Double gap) {
using (var enumerator = dashLengths.GetEnumerator()) {
if (enumerator.MoveNext())
yield return enumerator.Current;
while (enumerator.MoveNext()) {
yield return gap;
yield return enumerator.Current;
}
}
}
IEnumerable GetStrokeDashArray(IEnumerable DashLength,双间隙){
使用(var enumerator=dashLength.GetEnumerator()){
if(枚举数.MoveNext())
产生返回枚举数。当前;
while(枚举数.MoveNext()){
收益缺口;
产生返回枚举数。当前;
}
}
}
我认为最好的方法是为此创建一个特定的扩展方法:
public static IEnumerable<T> Intersperse<T>(this IEnumerable<T> source, T value)
{
bool first = true;
foreach(T item in source)
{
if (!first) yield return value;
yield return item;
first = false;
}
}
公共静态IEnumerable散布(此IEnumerable源,T值)
{
bool first=true;
foreach(源中的T项)
{
如果(!first)产生返回值;
收益回报项目;
第一个=假;
}
}
然后,您可以按如下方式编写方法:
public List<double> GetStrokeDashArray(List<double> dashLengths, double gap)
{
return dashLengths
.Intersperse(gap)
.ToList();
}
public List GetStrokeDashArray(List dashLength,双间隙)
{
返回划线长度
.穿插(间隙)
.ToList();
}
这是我能想到的最好的Zip
方法:
var gaps = Enumerable.Repeat(gap, dashLengths.Count - 1);
return dashLengths.Take(1)
.Concat(gaps.Zip(dashLengths.Skip(1), (x, y) => new[] {x, y})
.SelectMany(x => x))
.ToList();
不那么简洁。。。但是使用
Zip
+1作为答案,并命名方法Intersperse()
:)@DanM,这是一个有趣的名字吗?我认为它是正确的词,但英语不是我的母语,所以也许我错了;)我并不是想暗示它很有趣,它实际上是一个完美的词。有时很难想出正确的词,但你已经做到了。我正在标记这个答案(但如果有人真的想出一个比我更简洁的Linq本地表达,我可能会改变主意)。感谢您的帮助。+1由于显式使用枚举器,它比我的答案稍微有效一些。。。但您应该在完成后处置
枚举器;)@多谢你的提示。:-)+1是一个有趣的解决方案,但它在技术上不是Linq,也不能用于其他用途(以其当前的形式),所以我将使用Thomas的答案。@DanM:好吧,您只需将Double
替换为T
,将其作为扩展方法,并像Thomas那样重命名即可。但他已经给出了答案-D
var gaps = Enumerable.Repeat(gap, dashLengths.Count - 1);
return dashLengths.Take(1)
.Concat(gaps.Zip(dashLengths.Skip(1), (x, y) => new[] {x, y})
.SelectMany(x => x))
.ToList();