LINQ - 避免向HashSet添加空值

问题描述 投票:0回答:2

如何在IsNullOrEmpty之后避免将空(p.Trim())值添加到下面的linq列表中?

    HashSet<string> values;
    string[] value;
    ...  


    get { ... }
    set
    {
        value.ToList().ForEach(i => values.UnionWith(Array.ConvertAll(i.Split(';'), p => p.Trim())));
    }

变量声明仅用于说明目的。

c# .net linq validation
2个回答
3
投票

FWIW,我建议避免使用List.ForEach,请参阅Eric的博客文章:https://blogs.msdn.microsoft.com/ericlippert/2009/05/18/foreach-vs-foreach/

  • 您可以简化代码,如果您要将Linq方法添加到调用链中,则不需要调用ToList,因为这将导致列表中不必要的额外迭代。
  • 您还可以使用HashSet<T>(IEnumerable<T>)构造函数并简单地传入构造的Linq IEnumerable<T>(源数据仍然只能迭代一次)。
  • 如果你只是想要不同的值,你不需要使用HashSet,你可以使用Linq的.Distinct()方法。
  • 我把你的Array.ConvertAll(i.Split(';'), p => p.Trim())转换成了.SelectMany电话。

如果您只想要一个不同字符串列表,我的方法是:

String[] stringValues = ...
List<String> distinctValues = stringValues
    .SelectMany( v => v.Split(';') )
    .Select( v => v.Trim() )
    .Where( v => !String.IsNullOrEmpty( v ) )
    .Distinct()
    .ToList();

但如果你确实想要一个HashSet作为最终结果,那么你可以省略.Distinct步骤(确保你不要调用ToList!):

String[] stringValues = ...
IEnumerable<String> allValues = stringValues
    .SelectMany( v => v.Split(';') )
    .Select( v => v.Trim() )
    .Where( v => !String.IsNullOrEmpty( v ) );

HashSet<String> asHashSet = new HashSet<String>( allValues );

如果您需要不区分大小写的比较或其他比较逻辑,请使用接受自定义比较器的HashSet构造函数的其他重载。


0
投票

试试这个:

value.Select(s => !string.IsNullOrWhiteSpace(s)).ToList()
      .ForEach(i => values.UnionWith(Array.ConvertAll(i.Split(';'), p => p.Trim())));
© www.soinside.com 2019 - 2024. All rights reserved.