从LINQ中的选择字段连接拆分数组

时间:2014-04-14 14:40:13

标签: .net vb.net linq

我有一个字符串元素列表,每个元素都可以包含逗号分隔的值列表。从那时起,我想生成整个集合中所有不同值的列表。

以下列字符串为例:

Dim strings = New List(Of String) From {"A", "B,C,D", "D,E"}

我想把它变成:

{"A", "B", "C", "D", "E"}

使用linq,我可以将每个元素转换为字符串数组。以下查询将每个字符串拆分为一个数组,但它将保留在它自己的数组元素中。

Dim fieldsLinq = (From s In strings
                  Select s.Split(",")) _
                 .Distinct()

我想将所有值连接成一个字符串数组。

我可以先用逗号加入所有元素,然后分割单个字符串,但这感觉就像是错误的方法。

Dim fieldsJoin = String.Join(",", strings) _
                       .Split(",") _
                       .Distinct()

有没有更好的解决方案?

3 个答案:

答案 0 :(得分:3)

我不太了解VB,但您可以使用SelectMany来压缩阵列。在C#

strings.SelectMany(o=>o.Split(","));

答案 1 :(得分:1)

我认为Aggregate可以解决问题:

Dim fieldsAggregate = strings.Aggregate(New List(Of String), 
                                        Function(seed, s) 
                                            seed.AddRange(s.Split(","))
                                            Return seed
                                        End Function).Distinct()

更新:这是使用lambda和查询语法中SelectMany的murdock回答的VB版本:

Dim lambda = strings.SelectMany(Function(s) s.Split(",")) _ 
                    .Distinct()

Dim query = (From outer In strings
             From inner In outer.Split(",")
             Select inner) _
            .Distinct()

答案 2 :(得分:0)

我知道这可能与原始问题无关,但对于访问此页面的用户来说,搜索解决此问题的好方法可能仍然有用。在我看来,LINQ应该让开发人员的生活变得更加简单,短期和长期。

在这种特殊情况下,替代方法,即不使用LINQ,已经非常简单,并且更加可维护。通常情况下,如果您有像"A,B,D"这样的输入数据,那么从长远来看,您正在接近维护噩梦,因此很快就会将您的LINQ查询扩展到一个大怪物。

考虑这个代码,它做同样的事情(旧学校开始):

Private Shared Function AggregateSplit(input As List(Of String)) _
                                                             As List(Of String)
  Dim hsItems As New HashSet(Of String)
  For Each s As String In input
    AddRangeToHashSet(hsItems, s.Split(","))
  Next
  Return hsItems.ToList
End Function

Private Shared Sub AddRangeToHashSet(hsItems As HashSet(Of String),
                                     items As IEnumerable(Of String))
  For Each s As String In items
    If hsItems.Contains(s) Then Continue For
    hsItems.Add(s)
  Next
End Sub

用法:

Dim r = AggregateSplit(strings)

理想情况下,您已经使用AddRangeToHashSet作为扩展方法,因此每次需要AddRange时,您都不需要定义它。因此,在这种情况下,您需要声明AggregateSplit。还可以更容易地解释它对不熟悉LINQ的人所做的事情,如果某些事情没有得到很好的解析,你可以调试。