zip.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. package help
  2. // Zip applies a specified function to the corresponding elements of two
  3. // collections, producing a collection of the results.
  4. //
  5. // The method steps through the two input collections, applying function
  6. // resultSelector to corresponding elements of the two collections. The method
  7. // returns a collection of the values that are returned by resultSelector. If
  8. // the input collections do not have the same number of elements, the method
  9. // combines elements until it reaches the end of one of the collections. For
  10. // example, if one collection has three elements and the other one has four, the
  11. // result collection has only three elements.
  12. func (q Query) Zip(q2 Query,
  13. resultSelector func(interface{}, interface{}) interface{}) Query {
  14. return Query{
  15. Iterate: func() Iterator {
  16. next1 := q.Iterate()
  17. next2 := q2.Iterate()
  18. return func() (item interface{}, ok bool) {
  19. item1, ok1 := next1()
  20. item2, ok2 := next2()
  21. if ok1 && ok2 {
  22. return resultSelector(item1, item2), true
  23. }
  24. return nil, false
  25. }
  26. },
  27. }
  28. }
  29. // ZipT is the typed version of Zip.
  30. //
  31. // - resultSelectorFn is of type "func(TFirst,TSecond)TResult"
  32. //
  33. // NOTE: Zip has better performance than ZipT.
  34. func (q Query) ZipT(q2 Query,
  35. resultSelectorFn interface{}) Query {
  36. resultSelectorGenericFunc, err := newGenericFunc(
  37. "ZipT", "resultSelectorFn", resultSelectorFn,
  38. simpleParamValidator(newElemTypeSlice(new(genericType), new(genericType)), newElemTypeSlice(new(genericType))),
  39. )
  40. if err != nil {
  41. panic(err)
  42. }
  43. resultSelectorFunc := func(item1 interface{}, item2 interface{}) interface{} {
  44. return resultSelectorGenericFunc.Call(item1, item2)
  45. }
  46. return q.Zip(q2, resultSelectorFunc)
  47. }