【问题标题】:How to loop through two lists simultaneously?如何同时遍历两个列表?
【发布时间】:2011-08-03 14:21:14
【问题描述】:

我在Using foreach loop to iterate through two lists 提到了以下问题。关于选择的答案,我的问题是:o.DoSomething 可以比较吗?如:

For Each a in ListA.Concat(ListB)
    If(a from ListA=a from ListB) Then
        Do Something here
    End If
Next

正如您可能已经猜到的那样,我正在使用 VB.Net,并且想知道如何执行我在此处展示的内容。那基本上是分别/独立地遍历加入的列表。谢谢!

【问题讨论】:

  • @Dean:那里没有我可以使用的东西。这太复杂了,我现在正在使用.Net 4。 Zip 会起作用,但我该如何设置条件呢?另外,我使用的是列表,而不是 IEnums。你能告诉我这样做的正确方法吗?
  • 请记住,要对 IEnumerator(Of ListA) 采取行动,您需要做的就是调用 ListA.GetEnumerator() (显然对于两个列表)。我添加了一个编辑来说明如何使用 Zip
  • 对不起,伙计们,但我意识到我根本不需要这样做。我开始以不同的方式解决这个问题。不过非常感谢!在这个过程中学到了很多东西。

标签: vb.net list foreach


【解决方案1】:

您的问题表明您需要Join 操作,因为您不是要遍历两个列表,而是您还希望将一个列表中的类似项目匹配到另一个列表。

    Dim joinedLists = From item1 In list1 _
                    Join item2 In list2 _
                    On item1.Bar Equals item2.Bar _
                    Select New With {item1, item2}

    For Each pair In joinedLists
        'Do work on combined item here'
        'pair.item1'
        'pair.item2'
    Next

其他答案推荐Zip。这只是一个接受两个序列并产生一个结果的函数,很像 join,但它适用于在两个列表上以 FIFO 方法工作。如果您需要基于等式建立连接,Join 是专门为这项工作而构建的正确工具。

【讨论】:

  • +1 这是正确的,前提是您希望测试每个可能的组合是否相等,而不仅仅是两个列表中匹配索引位置的组合。我无法从想要的问题中决定。例如。 {0, 1, 2}{2, 0, 1} 应该报告没有匹配项还是报告三个匹配项?您的答案报告了三个匹配项 0=0 1=1 和 2=2。 @Akshay,你想要哪个?
【解决方案2】:

我的问题is-it-possible-to-iterate-over-two-ienumerable-objects-at-the-same-time 的答案可能会有所帮助

  Dim listA As List(Of A)
            Dim listb As List(Of B)

            listA.Zip(listb, Function(a, b) a.property1 = b.property1).ForEach(AddressOf Print)   


Shared Sub Print(ByVal s As A)
    Console.WriteLine(s.Property1)
End Sub

【讨论】:

  • 谢谢!到目前为止,我正在为每个使用嵌套,但效果不太好..:(将尝试 Zip 看看..
  • 谢谢! :) 会试试这个,让你知道。谢谢!
  • 那么这将返回一个布尔值的 IEnumerable,指示每对是否相等?问题的“在这里做点什么”部分呢?你将如何“在这里做点什么”?
  • 您可能会在此结束时使用 .ForEach(Action(Of T) 来分配一个代表来执行“做某事”我已经更新了示例给你一个粗略的想法,但是我觉得在我的链接中使用 GetEnumerator() 方法执行手动循环可能是他们前进的方向。
【解决方案3】:

在 .Net 4 中,您可以使用 Zip。改编自我对 this question 的回答,来自一位 Python 粉丝,专门询问 tuples - 如果您愿意,可以删除元组。

Sub Main()
    Dim arr1() As String = {"a", "b", "c"} '' will also work with Lists
    Dim arr2() As String = {"1", "2", "3"}
    For Each t In TupleSequence(arr1, arr2)
        If t.Item1 = t.Item2 Then
          '' Do something
        End If
    Next
    Console.ReadLine()
End Sub
Function TupleSequence(Of T1, T2)(
    ByVal seq1 As IEnumerable(Of T1),
    ByVal seq2 As IEnumerable(Of T2)
    ) As IEnumerable(Of Tuple(Of T1, T2))
    Return Enumerable.Zip(seq1, seq2, 
      Function(s1, s2) Tuple.Create(s1, s2)
    )
End Function

【讨论】:

  • 我试过 Zip,但是如何指定相等条件呢?如果你能给我语法,我很想试试。我自己尝试了一些东西。没用。有什么帮助吗?
  • @Akshay 不是在我的回答中吗? If t.Item1 = t.Item2 Then Do Something [with t.Item1 or t.Item2, presumably doesn't matter which one you use if they are equal]
【解决方案4】:

解决方案是拥有一个包含第二个列表中项目的字典,然后循环遍历第一个列表并使用字典检索第二个列表中的相应项目。这是一个示例,假设您要比较具有 ID 属性的项目:

Dim DictB = ListB.ToDictionary(Function(x) x.ID)
For each itemA in ListA
    If DictB.ContainsKey(itemA.ID)
        'Item is in both lists
        Dim itemB = DictB(itemA.ID)
        'Do something here
    End If
Next

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-26
    • 2011-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多