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