是否有更简洁的Linq表达式用于在列表中的每个项目之间插入常量?

时间:2012-03-24 01:19:41

标签: c# linq

这就是我现在所拥有的:

public List<double> GetStrokeDashArray(List<double> dashLengths, double gap)
{
    return dashLengths
        .SelectMany(dl => new[] { dl, gap })
        .Take(dashLengths.Count * 2 - 1)
        .ToList();
}

GetStrokeDashArray(new List<double> { 2, 4, 7, 11, 16 }, 2);

的结果
2, 2, 4, 2, 7, 2, 11, 2, 16

3 个答案:

答案 0 :(得分:8)

我认为最好的方法是为此创建一个特定的扩展方法:

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

然后您可以按如下方式编写方法:

public List<double> GetStrokeDashArray(List<double> dashLengths, double gap)
{
    return dashLengths
        .Intersperse(gap)
        .ToList();
}

答案 1 :(得分:3)

您可以改为使用迭代器块:

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

答案 2 :(得分:1)

我最好能为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