是否可以同时迭代两个IEnumerable对象?

Dea*_*ean 4 vb.net visual-studio-2005 .net-2.0

如果我有一个List(Of x)和一个List(Of y),是否可以同时迭代这两个?

就像是

for each _x as X, _y as Y in List(of x), List(of y) 
    if _x.item = _y.item then
        'do something
    end if
next
Run Code Online (Sandbox Code Playgroud)

这些列表可能具有不同的大小.

我正在使用.Net2.0,我怀疑这是我的垮台,因为我有一种感觉,LINQ可以通过加入常见id上的列表轻松解决问题.

Sco*_*ein 5

你可以使用一个老式的for循环.就像是

For ii As Integer = 0 To Math.Min(list1.Count, list2.Count)
    If list1(ii) = list2(ii) Then
    End If
Next
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这个答案,它很聪明. (2认同)

Joe*_*orn 5

IIRC,.Net 4.0将具有.Zip()已经实现的IEnumerable扩展方法。

同时,构建您自己的并不难。令人惊讶的是,尽管其他几个答案非常接近,但它们都存在至少一个问题。希望他们会得到纠正。同时,这应该在VB.Net中使用强类型的枚举器执行您想要的操作,对未知类型使用正确的比较,并正确处理枚举器:

Using xe As IEnumerator(Of X) = List1.GetEnumerator(), _
      ye As IEnumerator(Of Y) = List2.GetEnumerator()

    While xe.MoveNext() AndAlso ye.MoveNext() 
        If xe.Current.Equals(ye.Current) Then
            ''// do something
        End If
    End While
End Using
Run Code Online (Sandbox Code Playgroud)

现在,将其放入一个函数中,您可以将自己的委托传递给:

Public Shared Sub ZipAction(Of X, Y)(ByVal source1 As IEnumerable(Of X), ByVal source2 As IEnumerable(Of Y), _
                              ByVal compare As Func(Of X, Y, Boolean), Byval OnEquals As Action(Of X, Y))  

    Using xe As IEnumerator(Of X) = source1.GetEnumerator(), _
          ye As IEnumerator(Of Y) = source2.GetEnumerator()

        While xe.MoveNext() AndAlso ye.MoveNext() 
            If compare(xe.Current, ye.Current) Then
                OnEquals(xe.Current, ye.Current)
            End If
        End While
    End Using
End Sub
Run Code Online (Sandbox Code Playgroud)

最后,由于在.Net 3.5之前这些委托类型不可用,因此您可以像下面这样在.Net 2.0中轻松声明它们:

Public Delegate Sub Action(Of T1, T2) ( _
    arg1 As T1, _
    arg2 As T2 _
)

Public Delegate Function Func(Of T1, T2, TResult) ( _
    arg1 As T1, _
    arg2 As T2, _
) As TResult
Run Code Online (Sandbox Code Playgroud)

要使用此代码,您需要执行以下操作:

Public Class X
    Public Item As String
    ''//...
End Class

Public Class Y
    Public Item As String
    ''//...
End Class

Public Class Test

    Private Function CompareXtoY(ByVal arg1 As X, ByVal arg2 As Y) As Boolean
        Return arg1.Item = arg2.Item
    End Function

    Private Sub OnList1ItemMatchesList2Item(ByVal arg1 As X, ByVal arg2 As Y)
        ''// Do something...
    End Sub

    Private list1 As List(Of X) = GetXList()
    Private list2 As List(Of Y) = GetYList()

    Public Sub TestZip()
        ZipAction(list1, list2, AddressOf CompareXtoY, AddressOf OnList1ItemMatchesList2Item)
    End Sub

End Class
Run Code Online (Sandbox Code Playgroud)

如果这是C#,我将使该函数成为一个迭代器块,并在每个匹配对之间“让步收益”,而不是要求您传递Action委托。

  • 如果列表大小不同,则较长列表中剩余的项目将与较短列表中的任何项目都不匹配,因此无论如何都不会发生任何事情。 (2认同)