如何使用linq从vb.net中的键值对列表中的匹配键中获取值?

时间:2018-11-22 09:56:55

标签: vb.net linq

我想要键值对列表中的值,该键与给定数据匹配。 我的数据在列表中,如下所示

LeftExistingLayerName
(0)=>{[data1, 0.04#0]}
(1)=>{[data2, 0.04#0]}
(2)=>{[data3, 0.04#0]}

我已经使用以下代码获取单个值,例如匹配的data1

Dim LeftExistingLayerName As List(Of KeyValuePair(Of String, String)) = New List(Of KeyValuePair(Of String, String))
Dim result As String()
If LeftExistingLayerName.Where(Function(x) x.Key.Contains(g.LayerName)).Any() Then
Dim result1 = LeftExistingLayerName _                                                             
              .Where(Function(x) x.Key.Contains(g.LayerName)) _                                               
              .Select(Function(x) x.Value) _
             .ToString()
result = result1.Split(New String() {"#"}, StringSplitOptions.None)
End If

我想在字符串reslut1中获取值并拆分“#”,并取出result(0)中的值0.04和result1中的值0
我收到此错误

  

从字符串“ System.Linq.Enumerable + WhereSele”到“ Double”类型的转换无效

1 个答案:

答案 0 :(得分:1)

您没有显示导致问题的代码,因为错误指出“试图将字符串转换为双精度” 时出现问题。您的代码中没有任何东西可以说明这一点。

无论如何,要点...

字符串“ System.Linq.Enumerable + WhereSele” 显然不是要转换为双精度值的字符串。字符串表示形式来自以下事实:您正在调用ToString()子句返回的Enumerable上的Select,然后尝试将其转换为double。

鉴于您已经说过:

  

我已使用以下代码获取单个值,例如匹配的数据1

我们可以同意,您希望Enumerable查询返回一个单个值,正如@jmcilhinney在评论中建议的那样,有多种方法可以为您完成此操作,每种方法都针对具体情况。

  • 第一
  • FirstOrDefault
  • 单人
  • SingleOrDefault

我将让您研究将它们区分开的小细节,但就目前而言,例如,您可以使用FirstOrDefault

因此,您的代码变为:

Dim result As String = LeftExistingLayerName _                                                             
              .Where(Function(x) x.Key.Contains(g.LayerName)) _                                               
              .Select(Function(x) x.Value) _
              .FirstOrDefault()

读取为”,返回KeyValuePair的键包含g.LayerName的键值对的第一个值,否则返回引用类型的默认值”

因此,在这一点上,我们可以用定界符"#"分割字符串,然后将数组的第一,第二项转换为double或任何其他类型。

Dim array As String() = LeftExistingLayerName _                                                             
                  .Where(Function(x) x.Key.Contains(g.LayerName)) _                                               
                  .Select(Function(x) x.Value) _
                  .FirstOrDefault() _
                  .Split(New String() {"#"}, StringSplitOptions.None)
   ' array(0) gets the 0.04 part of your example
   ' array(1) gets the 0 part of your example

只要始终保证满足谓词Function(x) x.Key.Contains(s),这就足够了。否则,在由NullReferenceException返回的 null 引用上调用.Split时,将获得FirstOrDefault

如果要处理这种情况,则可以使用空传播运算符 (?)

Dim array As String() = LeftExistingLayerName _                                                             
                      .Where(Function(x) x.Key.Contains(g.LayerName)) _                                               
                      .Select(Function(x) x.Value) _
                      .FirstOrDefault() _
                      ?.Split(New String() {"#"}, StringSplitOptions.None)

顺便说一句,您可以简化:

If LeftExistingLayerName.Where(Function(x) x.Key.Contains(g.LayerName)).Any() Then

收件人:

If LeftExistingLayerName.Any(Function(x) x.Key.Contains(g.LayerName)) Then