where.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package help
  2. // Where filters a collection of values based on a predicate.
  3. func (q Query) Where(predicate func(interface{}) bool) Query {
  4. return Query{
  5. Iterate: func() Iterator {
  6. next := q.Iterate()
  7. return func() (item interface{}, ok bool) {
  8. for item, ok = next(); ok; item, ok = next() {
  9. if predicate(item) {
  10. return
  11. }
  12. }
  13. return
  14. }
  15. },
  16. }
  17. }
  18. // WhereT is the typed version of Where.
  19. //
  20. // - predicateFn is of type "func(TSource)bool"
  21. //
  22. // NOTE: Where has better performance than WhereT.
  23. func (q Query) WhereT(predicateFn interface{}) Query {
  24. predicateGenericFunc, err := newGenericFunc(
  25. "WhereT", "predicateFn", predicateFn,
  26. simpleParamValidator(newElemTypeSlice(new(genericType)), newElemTypeSlice(new(bool))),
  27. )
  28. if err != nil {
  29. panic(err)
  30. }
  31. predicateFunc := func(item interface{}) bool {
  32. return predicateGenericFunc.Call(item).(bool)
  33. }
  34. return q.Where(predicateFunc)
  35. }
  36. // WhereIndexed filters a collection of values based on a predicate. Each
  37. // element's index is used in the logic of the predicate function.
  38. //
  39. // The first argument represents the zero-based index of the element within
  40. // collection. The second argument of predicate represents the element to test.
  41. func (q Query) WhereIndexed(predicate func(int, interface{}) bool) Query {
  42. return Query{
  43. Iterate: func() Iterator {
  44. next := q.Iterate()
  45. index := 0
  46. return func() (item interface{}, ok bool) {
  47. for item, ok = next(); ok; item, ok = next() {
  48. if predicate(index, item) {
  49. index++
  50. return
  51. }
  52. index++
  53. }
  54. return
  55. }
  56. },
  57. }
  58. }
  59. // WhereIndexedT is the typed version of WhereIndexed.
  60. //
  61. // - predicateFn is of type "func(int,TSource)bool"
  62. //
  63. // NOTE: WhereIndexed has better performance than WhereIndexedT.
  64. func (q Query) WhereIndexedT(predicateFn interface{}) Query {
  65. predicateGenericFunc, err := newGenericFunc(
  66. "WhereIndexedT", "predicateFn", predicateFn,
  67. simpleParamValidator(newElemTypeSlice(new(int), new(genericType)), newElemTypeSlice(new(bool))),
  68. )
  69. if err != nil {
  70. panic(err)
  71. }
  72. predicateFunc := func(index int, item interface{}) bool {
  73. return predicateGenericFunc.Call(index, item).(bool)
  74. }
  75. return q.WhereIndexed(predicateFunc)
  76. }