我有一个字符串元素列表,每个元素都可以包含逗号分隔的值列表。由此,我想生成一个包含整个集合中所有不同值的列表。
以以下字符串集为例:
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()
有什么更好的解决方案吗?
我对VB不太了解,但您可以使用SelectMany来压平数组。在C#中
strings.SelectMany(o=>o.Split(","));
我想Aggregate
可以做到这一点:
Dim fieldsAggregate = strings.Aggregate(New List(Of String),
Function(seed, s)
seed.AddRange(s.Split(","))
Return seed
End Function).Distinct()
更新:这是murdock答案的VB版本,使用lambda中的SelectMany
和查询语法:
Dim lambda = strings.SelectMany(Function(s) s.Split(",")) _
.Distinct()
Dim query = (From outer In strings
From inner In outer.Split(",")
Select inner) _
.Distinct()
我知道这可能与最初的问题无关,但对于来到本页面寻找解决此问题的好方法的用户来说,这可能仍然很有用。在我看来,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的人来说,解释它的作用也要容易得多,如果某个东西解析不好,你可以进行调试。