linq 在空序列上使用Eccent.Aggregate(...)方法

hc2pp10m  于 2024-01-03  发布在  其他
关注(0)|答案(5)|浏览(193)

我想使用 * Esclent.Aggregate(...)* 方法来连接一个由字符串分隔的字符串列表。相当简单,不是吗?
考虑到以下情况:

  • private const string LISTSEPARATOR = "; ";
  • *album.*OrderedTracks is List<TrackDetails>
  • TrackDetails 具有 DiscNumber Int16?属性

如果 Distinct() 返回的序列为空(因为 Aggregate() 方法不适用于空序列),则以下语句将抛出异常:

  1. txtDiscNumber.Text = album.OrderedTracks
  2. .Where(a => a.DiscNumber.HasValue)
  3. .Select(a => a.DiscNumber.Value.ToString())
  4. .Distinct()
  5. .Aggregate((i, j) => i + LISTSEPARATOR + j);

字符串
我正在使用的工作区:

  1. List<string> DiscNumbers =
  2. album.OrderedTracks
  3. .Where(a => a.DiscNumber.HasValue)
  4. .Select(a => a.DiscNumber.Value.ToString())
  5. .Distinct()
  6. .ToList();
  7. if (!DiscNumbers.Any())
  8. txtDiscNumber.Text = null;
  9. else
  10. txtDiscNumber.Text =
  11. DiscNumbers.Aggregate((i, j) => i + LISTSEPARATOR + j);


有没有更好的解决方案?有没有可能在一个LINQ语句中做到这一点?
先谢了。

lsmd5eda

lsmd5eda1#

要连接字符串列表,请使用string.Join方法。
Aggregate函数不能处理空集合。它需要一个二进制累加函数,并且需要集合中的一个项作为种子值传递给二进制函数。
但是,有一个overload of Aggregate

  1. public static TResult Aggregate<TSource, TAccumulate, TResult>(
  2. this IEnumerable<TSource> source,
  3. TAccumulate seed,
  4. Func<TAccumulate, TSource, TAccumulate> func,
  5. Func<TAccumulate, TResult> resultSelector
  6. )

字符串
此重载允许您指定种子值。如果指定了种子值,则在集合为空时也将使用该值作为结果。

**编辑:**如果你真的想使用Aggregate,你可以这样做:

  1. sequence.Aggregate(string.Empty, (x, y) => x == string.Empty ? y : x + Separator + y)


使用StringBuilder

  1. sequence.Aggregate(new StringBuilder(), (sb, x) => (sb.Length == 0 ? sb : sb.Append(Separator)).Append(x)).ToString()

展开查看全部
brqmpdu1

brqmpdu12#

我想你可能会发现下面的辅助扩展方法很有用。

  1. public static TOut Pipe<TIn, TOut>(this TIn _this, Func<TIn, TOut> func)
  2. {
  3. return func(_this);
  4. }

字符串
它允许您以以下方式表达查询。

  1. txtDiscNumber.Text = album.OrderedTracks
  2. .Where(a => a.DiscNumber.HasValue)
  3. .Select(a => a.DiscNumber.Value.ToString())
  4. .Distinct()
  5. .Pipe(items => string.Join(LISTSEPARATOR, items));


这仍然是“从上到下”,这极大地提高了可读性。

展开查看全部
izkcnapc

izkcnapc3#

您可以使用

  1. .Aggregate(string.Empty, (acc, name) => acc + (acc.Length > 0 ? separator : string.Empty) + name)

字符串
对于初始值,它适用于空集合,但对于长度检查,

34gzjxbg

34gzjxbg4#

使用String.Join如下:

  1. txtDiscNumber.Text = String.Join(LISTSEPARATOR,
  2. album.OrderedTracks
  3. .Where(a => a.DiscNumber.HasValue)
  4. .Select(a => a.DiscNumber.Value.ToString())
  5. .Distinct());

字符串

dgtucam1

dgtucam15#

为了调试的目的,我经常使用这样的方法,我想出了两个扩展方法:

  1. public static string Concatenate<T, U>(this IEnumerable<T> source, Func<T, U> selector, string separator = ", ")
  2. {
  3. if (source == null)
  4. {
  5. return string.Empty;
  6. }
  7. return source
  8. .Select(selector)
  9. .Concatenate(separator);
  10. }
  11. public static string Concatenate<T>(this IEnumerable<T> source, string separator = ", ")
  12. {
  13. if (source == null)
  14. {
  15. return string.Empty;
  16. }
  17. StringBuilder sb = new StringBuilder();
  18. bool firstPass = true;
  19. foreach (string item in source.Distinct().Select(x => x.ToString()))
  20. {
  21. if (firstPass)
  22. {
  23. firstPass = false;
  24. }
  25. else
  26. {
  27. sb.Append(separator);
  28. }
  29. sb.Append(item);
  30. }
  31. return sb.ToString();
  32. }

字符串
像这样使用:

  1. string myLine = myCol.Concatenate(x => x.TheProperty);

展开查看全部

相关问题