result.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. package help
  2. import (
  3. "math"
  4. "reflect"
  5. )
  6. // All determines whether all elements of a collection satisfy a condition.
  7. func (q Query) All(predicate func(interface{}) bool) bool {
  8. next := q.Iterate()
  9. for item, ok := next(); ok; item, ok = next() {
  10. if !predicate(item) {
  11. return false
  12. }
  13. }
  14. return true
  15. }
  16. // AllT is the typed version of All.
  17. //
  18. // - predicateFn is of type "func(TSource) bool"
  19. //
  20. // NOTE: All has better performance than AllT.
  21. func (q Query) AllT(predicateFn interface{}) bool {
  22. predicateGenericFunc, err := newGenericFunc(
  23. "AllT", "predicateFn", predicateFn,
  24. simpleParamValidator(newElemTypeSlice(new(genericType)), newElemTypeSlice(new(bool))),
  25. )
  26. if err != nil {
  27. panic(err)
  28. }
  29. predicateFunc := func(item interface{}) bool {
  30. return predicateGenericFunc.Call(item).(bool)
  31. }
  32. return q.All(predicateFunc)
  33. }
  34. // Any determines whether any element of a collection exists.
  35. func (q Query) Any() bool {
  36. _, ok := q.Iterate()()
  37. return ok
  38. }
  39. // AnyWith determines whether any element of a collection satisfies a condition.
  40. func (q Query) AnyWith(predicate func(interface{}) bool) bool {
  41. next := q.Iterate()
  42. for item, ok := next(); ok; item, ok = next() {
  43. if predicate(item) {
  44. return true
  45. }
  46. }
  47. return false
  48. }
  49. // AnyWithT is the typed version of AnyWith.
  50. //
  51. // - predicateFn is of type "func(TSource) bool"
  52. //
  53. // NOTE: AnyWith has better performance than AnyWithT.
  54. func (q Query) AnyWithT(predicateFn interface{}) bool {
  55. predicateGenericFunc, err := newGenericFunc(
  56. "AnyWithT", "predicateFn", predicateFn,
  57. simpleParamValidator(newElemTypeSlice(new(genericType)), newElemTypeSlice(new(bool))),
  58. )
  59. if err != nil {
  60. panic(err)
  61. }
  62. predicateFunc := func(item interface{}) bool {
  63. return predicateGenericFunc.Call(item).(bool)
  64. }
  65. return q.AnyWith(predicateFunc)
  66. }
  67. // Average computes the average of a collection of numeric values.
  68. func (q Query) Average() (r float64) {
  69. next := q.Iterate()
  70. item, ok := next()
  71. if !ok {
  72. return math.NaN()
  73. }
  74. n := 1
  75. switch item.(type) {
  76. case int, int8, int16, int32, int64:
  77. conv := getIntConverter(item)
  78. sum := conv(item)
  79. for item, ok = next(); ok; item, ok = next() {
  80. sum += conv(item)
  81. n++
  82. }
  83. r = float64(sum)
  84. case uint, uint8, uint16, uint32, uint64:
  85. conv := getUIntConverter(item)
  86. sum := conv(item)
  87. for item, ok = next(); ok; item, ok = next() {
  88. sum += conv(item)
  89. n++
  90. }
  91. r = float64(sum)
  92. default:
  93. conv := getFloatConverter(item)
  94. r = conv(item)
  95. for item, ok = next(); ok; item, ok = next() {
  96. r += conv(item)
  97. n++
  98. }
  99. }
  100. return r / float64(n)
  101. }
  102. // Contains determines whether a collection contains a specified element.
  103. func (q Query) Contains(value interface{}) bool {
  104. next := q.Iterate()
  105. for item, ok := next(); ok; item, ok = next() {
  106. if item == value {
  107. return true
  108. }
  109. }
  110. return false
  111. }
  112. // Count returns the number of elements in a collection.
  113. func (q Query) Count() (r int) {
  114. next := q.Iterate()
  115. for _, ok := next(); ok; _, ok = next() {
  116. r++
  117. }
  118. return
  119. }
  120. // CountWith returns a number that represents how many elements in the specified
  121. // collection satisfy a condition.
  122. func (q Query) CountWith(predicate func(interface{}) bool) (r int) {
  123. next := q.Iterate()
  124. for item, ok := next(); ok; item, ok = next() {
  125. if predicate(item) {
  126. r++
  127. }
  128. }
  129. return
  130. }
  131. // CountWithT is the typed version of CountWith.
  132. //
  133. // - predicateFn is of type "func(TSource) bool"
  134. //
  135. // NOTE: CountWith has better performance than CountWithT.
  136. func (q Query) CountWithT(predicateFn interface{}) int {
  137. predicateGenericFunc, err := newGenericFunc(
  138. "CountWithT", "predicateFn", predicateFn,
  139. simpleParamValidator(newElemTypeSlice(new(genericType)), newElemTypeSlice(new(bool))),
  140. )
  141. if err != nil {
  142. panic(err)
  143. }
  144. predicateFunc := func(item interface{}) bool {
  145. return predicateGenericFunc.Call(item).(bool)
  146. }
  147. return q.CountWith(predicateFunc)
  148. }
  149. // First returns the first element of a collection.
  150. func (q Query) First() interface{} {
  151. item, _ := q.Iterate()()
  152. return item
  153. }
  154. // FirstWith returns the first element of a collection that satisfies a
  155. // specified condition.
  156. func (q Query) FirstWith(predicate func(interface{}) bool) interface{} {
  157. next := q.Iterate()
  158. for item, ok := next(); ok; item, ok = next() {
  159. if predicate(item) {
  160. return item
  161. }
  162. }
  163. return nil
  164. }
  165. // FirstWithT is the typed version of FirstWith.
  166. //
  167. // - predicateFn is of type "func(TSource) bool"
  168. //
  169. // NOTE: FirstWith has better performance than FirstWithT.
  170. func (q Query) FirstWithT(predicateFn interface{}) interface{} {
  171. predicateGenericFunc, err := newGenericFunc(
  172. "FirstWithT", "predicateFn", predicateFn,
  173. simpleParamValidator(newElemTypeSlice(new(genericType)), newElemTypeSlice(new(bool))),
  174. )
  175. if err != nil {
  176. panic(err)
  177. }
  178. predicateFunc := func(item interface{}) bool {
  179. return predicateGenericFunc.Call(item).(bool)
  180. }
  181. return q.FirstWith(predicateFunc)
  182. }
  183. // ForEach performs the specified action on each element of a collection.
  184. func (q Query) ForEach(action func(interface{})) {
  185. next := q.Iterate()
  186. for item, ok := next(); ok; item, ok = next() {
  187. action(item)
  188. }
  189. }
  190. // ForEachT is the typed version of ForEach.
  191. //
  192. // - actionFn is of type "func(TSource)"
  193. //
  194. // NOTE: ForEach has better performance than ForEachT.
  195. func (q Query) ForEachT(actionFn interface{}) {
  196. actionGenericFunc, err := newGenericFunc(
  197. "ForEachT", "actionFn", actionFn,
  198. simpleParamValidator(newElemTypeSlice(new(genericType)), nil),
  199. )
  200. if err != nil {
  201. panic(err)
  202. }
  203. actionFunc := func(item interface{}) {
  204. actionGenericFunc.Call(item)
  205. }
  206. q.ForEach(actionFunc)
  207. }
  208. // ForEachIndexed performs the specified action on each element of a collection.
  209. //
  210. // The first argument to action represents the zero-based index of that
  211. // element in the source collection. This can be useful if the elements are in a
  212. // known order and you want to do something with an element at a particular
  213. // index, for example. It can also be useful if you want to retrieve the index
  214. // of one or more elements. The second argument to action represents the
  215. // element to process.
  216. func (q Query) ForEachIndexed(action func(int, interface{})) {
  217. next := q.Iterate()
  218. index := 0
  219. for item, ok := next(); ok; item, ok = next() {
  220. action(index, item)
  221. index++
  222. }
  223. }
  224. // ForEachIndexedT is the typed version of ForEachIndexed.
  225. //
  226. // - actionFn is of type "func(int, TSource)"
  227. //
  228. // NOTE: ForEachIndexed has better performance than ForEachIndexedT.
  229. func (q Query) ForEachIndexedT(actionFn interface{}) {
  230. actionGenericFunc, err := newGenericFunc(
  231. "ForEachIndexedT", "actionFn", actionFn,
  232. simpleParamValidator(newElemTypeSlice(new(int), new(genericType)), nil),
  233. )
  234. if err != nil {
  235. panic(err)
  236. }
  237. actionFunc := func(index int, item interface{}) {
  238. actionGenericFunc.Call(index, item)
  239. }
  240. q.ForEachIndexed(actionFunc)
  241. }
  242. // Last returns the last element of a collection.
  243. func (q Query) Last() (r interface{}) {
  244. next := q.Iterate()
  245. for item, ok := next(); ok; item, ok = next() {
  246. r = item
  247. }
  248. return
  249. }
  250. // LastWith returns the last element of a collection that satisfies a specified
  251. // condition.
  252. func (q Query) LastWith(predicate func(interface{}) bool) (r interface{}) {
  253. next := q.Iterate()
  254. for item, ok := next(); ok; item, ok = next() {
  255. if predicate(item) {
  256. r = item
  257. }
  258. }
  259. return
  260. }
  261. // LastWithT is the typed version of LastWith.
  262. //
  263. // - predicateFn is of type "func(TSource) bool"
  264. //
  265. // NOTE: LastWith has better performance than LastWithT.
  266. func (q Query) LastWithT(predicateFn interface{}) interface{} {
  267. predicateGenericFunc, err := newGenericFunc(
  268. "LastWithT", "predicateFn", predicateFn,
  269. simpleParamValidator(newElemTypeSlice(new(genericType)), newElemTypeSlice(new(bool))),
  270. )
  271. if err != nil {
  272. panic(err)
  273. }
  274. predicateFunc := func(item interface{}) bool {
  275. return predicateGenericFunc.Call(item).(bool)
  276. }
  277. return q.LastWith(predicateFunc)
  278. }
  279. // Max returns the maximum value in a collection of values.
  280. func (q Query) Max() (r interface{}) {
  281. next := q.Iterate()
  282. item, ok := next()
  283. if !ok {
  284. return nil
  285. }
  286. compare := getComparer(item)
  287. r = item
  288. for item, ok := next(); ok; item, ok = next() {
  289. if compare(item, r) > 0 {
  290. r = item
  291. }
  292. }
  293. return
  294. }
  295. // Min returns the minimum value in a collection of values.
  296. func (q Query) Min() (r interface{}) {
  297. next := q.Iterate()
  298. item, ok := next()
  299. if !ok {
  300. return nil
  301. }
  302. compare := getComparer(item)
  303. r = item
  304. for item, ok := next(); ok; item, ok = next() {
  305. if compare(item, r) < 0 {
  306. r = item
  307. }
  308. }
  309. return
  310. }
  311. // Results iterates over a collection and returnes slice of interfaces
  312. func (q Query) Results() (r []interface{}) {
  313. next := q.Iterate()
  314. for item, ok := next(); ok; item, ok = next() {
  315. r = append(r, item)
  316. }
  317. return
  318. }
  319. // SequenceEqual determines whether two collections are equal.
  320. func (q Query) SequenceEqual(q2 Query) bool {
  321. next := q.Iterate()
  322. next2 := q2.Iterate()
  323. for item, ok := next(); ok; item, ok = next() {
  324. item2, ok2 := next2()
  325. if !ok2 || item != item2 {
  326. return false
  327. }
  328. }
  329. _, ok2 := next2()
  330. return !ok2
  331. }
  332. // Single returns the only element of a collection, and nil if there is not
  333. // exactly one element in the collection.
  334. func (q Query) Single() interface{} {
  335. next := q.Iterate()
  336. item, ok := next()
  337. if !ok {
  338. return nil
  339. }
  340. _, ok = next()
  341. if ok {
  342. return nil
  343. }
  344. return item
  345. }
  346. // SingleWith returns the only element of a collection that satisfies a
  347. // specified condition, and nil if more than one such element exists.
  348. func (q Query) SingleWith(predicate func(interface{}) bool) (r interface{}) {
  349. next := q.Iterate()
  350. found := false
  351. for item, ok := next(); ok; item, ok = next() {
  352. if predicate(item) {
  353. if found {
  354. return nil
  355. }
  356. found = true
  357. r = item
  358. }
  359. }
  360. return
  361. }
  362. // SingleWithT is the typed version of SingleWith.
  363. //
  364. // - predicateFn is of type "func(TSource) bool"
  365. //
  366. // NOTE: SingleWith has better performance than SingleWithT.
  367. func (q Query) SingleWithT(predicateFn interface{}) interface{} {
  368. predicateGenericFunc, err := newGenericFunc(
  369. "SingleWithT", "predicateFn", predicateFn,
  370. simpleParamValidator(newElemTypeSlice(new(genericType)), newElemTypeSlice(new(bool))),
  371. )
  372. if err != nil {
  373. panic(err)
  374. }
  375. predicateFunc := func(item interface{}) bool {
  376. return predicateGenericFunc.Call(item).(bool)
  377. }
  378. return q.SingleWith(predicateFunc)
  379. }
  380. // SumInts computes the sum of a collection of numeric values.
  381. //
  382. // Values can be of any integer type: int, int8, int16, int32, int64. The result
  383. // is int64. Method returns zero if collection contains no elements.
  384. func (q Query) SumInts() (r int64) {
  385. next := q.Iterate()
  386. item, ok := next()
  387. if !ok {
  388. return 0
  389. }
  390. conv := getIntConverter(item)
  391. r = conv(item)
  392. for item, ok = next(); ok; item, ok = next() {
  393. r += conv(item)
  394. }
  395. return
  396. }
  397. // SumUInts computes the sum of a collection of numeric values.
  398. //
  399. // Values can be of any unsigned integer type: uint, uint8, uint16, uint32,
  400. // uint64. The result is uint64. Method returns zero if collection contains no
  401. // elements.
  402. func (q Query) SumUInts() (r uint64) {
  403. next := q.Iterate()
  404. item, ok := next()
  405. if !ok {
  406. return 0
  407. }
  408. conv := getUIntConverter(item)
  409. r = conv(item)
  410. for item, ok = next(); ok; item, ok = next() {
  411. r += conv(item)
  412. }
  413. return
  414. }
  415. // SumFloats computes the sum of a collection of numeric values.
  416. //
  417. // Values can be of any float type: float32 or float64. The result is float64.
  418. // Method returns zero if collection contains no elements.
  419. func (q Query) SumFloats() (r float64) {
  420. next := q.Iterate()
  421. item, ok := next()
  422. if !ok {
  423. return 0
  424. }
  425. conv := getFloatConverter(item)
  426. r = conv(item)
  427. for item, ok = next(); ok; item, ok = next() {
  428. r += conv(item)
  429. }
  430. return
  431. }
  432. // ToChannel iterates over a collection and outputs each element to a channel,
  433. // then closes it.
  434. func (q Query) ToChannel(result chan<- interface{}) {
  435. next := q.Iterate()
  436. for item, ok := next(); ok; item, ok = next() {
  437. result <- item
  438. }
  439. close(result)
  440. }
  441. // ToChannelT is the typed version of ToChannel.
  442. //
  443. // - result is of type "chan TSource"
  444. //
  445. // NOTE: ToChannel has better performance than ToChannelT.
  446. func (q Query) ToChannelT(result interface{}) {
  447. r := reflect.ValueOf(result)
  448. next := q.Iterate()
  449. for item, ok := next(); ok; item, ok = next() {
  450. r.Send(reflect.ValueOf(item))
  451. }
  452. r.Close()
  453. }
  454. // ToMap iterates over a collection and populates result map with elements.
  455. // Collection elements have to be of KeyValue type to use this method. To
  456. // populate a map with elements of different type use ToMapBy method. ToMap
  457. // doesn't empty the result map before populating it.
  458. func (q Query) ToMap(result interface{}) {
  459. q.ToMapBy(
  460. result,
  461. func(i interface{}) interface{} {
  462. return i.(KeyValue).Key
  463. },
  464. func(i interface{}) interface{} {
  465. return i.(KeyValue).Value
  466. })
  467. }
  468. // ToMapBy iterates over a collection and populates the result map with
  469. // elements. Functions keySelector and valueSelector are executed for each
  470. // element of the collection to generate key and value for the map. Generated
  471. // key and value types must be assignable to the map's key and value types.
  472. // ToMapBy doesn't empty the result map before populating it.
  473. func (q Query) ToMapBy(result interface{},
  474. keySelector func(interface{}) interface{},
  475. valueSelector func(interface{}) interface{}) {
  476. res := reflect.ValueOf(result)
  477. m := reflect.Indirect(res)
  478. next := q.Iterate()
  479. for item, ok := next(); ok; item, ok = next() {
  480. key := reflect.ValueOf(keySelector(item))
  481. value := reflect.ValueOf(valueSelector(item))
  482. m.SetMapIndex(key, value)
  483. }
  484. res.Elem().Set(m)
  485. }
  486. // ToMapByT is the typed version of ToMapBy.
  487. //
  488. // - keySelectorFn is of type "func(TSource)TKey"
  489. // - valueSelectorFn is of type "func(TSource)TValue"
  490. //
  491. // NOTE: ToMapBy has better performance than ToMapByT.
  492. func (q Query) ToMapByT(result interface{},
  493. keySelectorFn interface{}, valueSelectorFn interface{}) {
  494. keySelectorGenericFunc, err := newGenericFunc(
  495. "ToMapByT", "keySelectorFn", keySelectorFn,
  496. simpleParamValidator(newElemTypeSlice(new(genericType)), newElemTypeSlice(new(genericType))),
  497. )
  498. if err != nil {
  499. panic(err)
  500. }
  501. keySelectorFunc := func(item interface{}) interface{} {
  502. return keySelectorGenericFunc.Call(item)
  503. }
  504. valueSelectorGenericFunc, err := newGenericFunc(
  505. "ToMapByT", "valueSelectorFn", valueSelectorFn,
  506. simpleParamValidator(newElemTypeSlice(new(genericType)), newElemTypeSlice(new(genericType))),
  507. )
  508. if err != nil {
  509. panic(err)
  510. }
  511. valueSelectorFunc := func(item interface{}) interface{} {
  512. return valueSelectorGenericFunc.Call(item)
  513. }
  514. q.ToMapBy(result, keySelectorFunc, valueSelectorFunc)
  515. }
  516. // ToSlice iterates over a collection and saves the results in the slice pointed
  517. // by v. It overwrites the existing slice, starting from index 0.
  518. //
  519. // If the slice pointed by v has sufficient capacity, v will be pointed to a
  520. // resliced slice. If it does not, a new underlying array will be allocated and
  521. // v will point to it.
  522. func (q Query) ToSlice(v interface{}) {
  523. res := reflect.ValueOf(v)
  524. slice := reflect.Indirect(res)
  525. cap := slice.Cap()
  526. res.Elem().Set(slice.Slice(0, cap)) // make len(slice)==cap(slice) from now on
  527. next := q.Iterate()
  528. index := 0
  529. for item, ok := next(); ok; item, ok = next() {
  530. if index >= cap {
  531. slice, cap = grow(slice)
  532. }
  533. slice.Index(index).Set(reflect.ValueOf(item))
  534. index++
  535. }
  536. // reslice the len(res)==cap(res) actual res size
  537. res.Elem().Set(slice.Slice(0, index))
  538. }
  539. // grow grows the slice s by doubling its capacity, then it returns the new
  540. // slice (resliced to its full capacity) and the new capacity.
  541. func grow(s reflect.Value) (v reflect.Value, newCap int) {
  542. cap := s.Cap()
  543. if cap == 0 {
  544. cap = 1
  545. } else {
  546. cap *= 2
  547. }
  548. newSlice := reflect.MakeSlice(s.Type(), cap, cap)
  549. reflect.Copy(newSlice, s)
  550. return newSlice, cap
  551. }