是否可以同时迭代两个IEnumerable对象? [英] Is it possible to iterate over two IEnumerable objects at the same time?
问题描述
如果我有一个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屋!