LINQ-避免将空值添加到HashSet

时间:2018-09-05 17:50:01

标签: c# .net linq validation

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

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


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

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

2 个答案:

答案 0 :(得分: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构造函数的其他重载,这些重载接受自定义比较器。

答案 1 :(得分:0)

尝试一下:

value.Select(s => !string.IsNullOrWhiteSpace(s)).ToList()
      .ForEach(i => values.UnionWith(Array.ConvertAll(i.Split(';'), p => p.Trim())));