是否可以同时迭代两个IEnumerable对象? [英] Is it possible to iterate over two IEnumerable objects at the same time?

查看:86
本文介绍了是否可以同时迭代两个IEnumerable对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一个List(Of x)和一个List(Of y),是否可以同时遍历两者?

If I have a List(Of x) and a List(Of y) is it possible to iterate over both at the same time?

类似

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

这些列表的大小可能不同。

These lists may be of differing sizes.

我正在使用.Net2.0,我怀疑这是我的失败,因为我感觉LINQ可以通过加入公共ID来轻松解决类似问题。

I am using .Net2.0 which I suspect is my downfall here as I have a feeling LINQ would solve something like easily by joining the lists on there common id.

推荐答案

IIRC,.Net 4.0将具有 .Zip()

IIRC, .Net 4.0 will have a .Zip() extension method for IEnumerable that already does this.

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

In the meantime, it's not that hard to build your own. Surprisingly, while several other answers were very close they all have a least one problem. Hopefully they will be corrected. In the meantime, this should do what you want it to, in VB.Net, with strongly-typed enumerators, using a correct comparison for the unknown types, and correctly dispose of the enumerators:

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

现在让我们将其放入一个函数中可以将自己的代表传递给:

And now let's put this into a function that you can pass your own delegates to:

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

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

And finally, since those delegate types aren't available until .Net 3.5 you can easily declare them in .Net 2.0 like this:

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

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

To use this code, you'd do something like this:

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

如果这是C#,我可以函数是一个迭代器块,并在每个匹配对之间收益回报,而不是要求您传递Action委托。

If this were C#, I would have the function be an iterator block and "yield return" each matching pair rather than asking you to pass in an Action delegate.

这篇关于是否可以同时迭代两个IEnumerable对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆