C# LINQ-避免向哈希集添加空值

C# LINQ-避免向哈希集添加空值,c#,.net,linq,validation,C#,.net,Linq,Validation,如何避免在p.Trim()之后将空(IsNullOrEmpty)值添加到下面linq中的列表中 HashSet值; 字符串[]值; ... 获取{…} 设置 { value.ToList().ForEach(i=>values.UnionWith(Array.ConvertAll(i.Split(“;”),p=>p.Trim()); } 变量声明仅用于说明目的。尝试以下方法: value.Select(s => !string.IsNullOrWhiteSpace(s)).ToLis

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

HashSet值;
字符串[]值;
...  
获取{…}
设置
{
value.ToList().ForEach(i=>values.UnionWith(Array.ConvertAll(i.Split(“;”),p=>p.Trim());
}
变量声明仅用于说明目的。

尝试以下方法:

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

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

FWIW,我建议避免使用
列表。ForEach
,请参阅Eric的博客文章:

  • 您可以简化代码,如果要将Linq方法添加到调用链中,则无需调用
    ToList
    ,因为这将导致列表中不必要的额外迭代
  • 您还可以使用
    HashSet(IEnumerable)
    构造函数,只需传入构造好的Linq
    IEnumerable
    (源数据仍将只迭代一次)
  • 如果您只需要不同的值,而不需要使用
    HashSet
    ,那么可以使用Linq的
    .distinct()
    方法
  • 我将您的
    数组.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
构造函数的其他重载。

FWIW,我建议避免使用
List。ForEach
,请参阅Eric的博客文章:

  • 您可以简化代码,如果要将Linq方法添加到调用链中,则无需调用
    ToList
    ,因为这将导致列表中不必要的额外迭代
  • 您还可以使用
    HashSet(IEnumerable)
    构造函数,只需传入构造好的Linq
    IEnumerable
    (源数据仍将只迭代一次)
  • 如果您只需要不同的值,而不需要使用
    HashSet
    ,那么可以使用Linq的
    .distinct()
    方法
  • 我将您的
    数组.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
构造函数的其他重载。

value.Where(s=>!string.IsNullOrEmpty(s)).ToList().ForEach
…无需调用
value.ToList().ForEach
-您可以直接迭代
,或使用
选择
。使用Linq时,从功能上考虑!(也就是说,Linq调用不应该有副作用,因为您的代码执行的是
值。UnionWith
,它直接变异
哈希集
)。@Dai yea。好idea@ParrishHusband对于输入“abc;;efg;”?@JimsonKannantharaJames请查看Dai的答案,它非常适合您尝试执行的操作。
value.Where(s=>!string.IsNullOrEmpty(s)).ToList().ForEach
…您不需要调用
value.ToList().ForEach
-您可以直接迭代
,或使用
选择
。使用Linq时,从功能上考虑!(也就是说,Linq调用不应该有副作用,因为您的代码执行的是
值。UnionWith
,它直接变异
哈希集
)。@Dai yea。好idea@ParrishHusband输入“abc;;efg;”是否有效?@JimsonKannantharaJames查看Dai的答案,它非常适合你要做的事情。@parrishhurt No man。但是如果你想要你的答案,我删除我的答案,我们可能都错过了额外的括号:)这不会编译,因为
值。选择(…)
返回一个
IEnumerable
,而Linq不定义
。ForEach
扩展方法用于
IEnumerable
(它只存在于
列表中)“帕里什先生没有男人。但是如果你想要你的答案,我删除我的答案,我们可能都错过了额外的括号:)这不会编译,因为
值。选择(…)
返回一个
IEnumerable
,而Linq不定义
。ForEach
扩展方法用于
IEnumerable
(它只存在于
列表中)。非常干净的方法,我喜欢将
IEnumerable
直接传递到
HashSet
中,没有必要删除重复值两次。您只是在冗余地构造两个不同的集合。@Servy cool我没有意识到构造函数在幕后调用了
UnionWith
。@Servy我已经修改了我的答案。非常干净的方法,我喜欢您将
IEnumerable
直接传递到
HashSet
中,没有必要删除重复值两次。你只是在冗余地构造两个不同的集合。@Servy cool我没有意识到构造函数在幕后调用了
UnionWith
。@Servy我已经修改了我的答案。