list.go 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. package sprig
  2. import (
  3. "fmt"
  4. "math"
  5. "reflect"
  6. "sort"
  7. )
  8. // Reflection is used in these functions so that slices and arrays of strings,
  9. // ints, and other types not implementing []any can be worked with.
  10. // For example, this is useful if you need to work on the output of regexs.
  11. func list(v ...any) []any {
  12. return v
  13. }
  14. func push(list any, v any) []any {
  15. l, err := mustPush(list, v)
  16. if err != nil {
  17. panic(err)
  18. }
  19. return l
  20. }
  21. func mustPush(list any, v any) ([]any, error) {
  22. tp := reflect.TypeOf(list).Kind()
  23. switch tp {
  24. case reflect.Slice, reflect.Array:
  25. l2 := reflect.ValueOf(list)
  26. l := l2.Len()
  27. nl := make([]any, l)
  28. for i := 0; i < l; i++ {
  29. nl[i] = l2.Index(i).Interface()
  30. }
  31. return append(nl, v), nil
  32. default:
  33. return nil, fmt.Errorf("cannot push on type %s", tp)
  34. }
  35. }
  36. func prepend(list any, v any) []any {
  37. l, err := mustPrepend(list, v)
  38. if err != nil {
  39. panic(err)
  40. }
  41. return l
  42. }
  43. func mustPrepend(list any, v any) ([]any, error) {
  44. //return append([]any{v}, list...)
  45. tp := reflect.TypeOf(list).Kind()
  46. switch tp {
  47. case reflect.Slice, reflect.Array:
  48. l2 := reflect.ValueOf(list)
  49. l := l2.Len()
  50. nl := make([]any, l)
  51. for i := 0; i < l; i++ {
  52. nl[i] = l2.Index(i).Interface()
  53. }
  54. return append([]any{v}, nl...), nil
  55. default:
  56. return nil, fmt.Errorf("cannot prepend on type %s", tp)
  57. }
  58. }
  59. func chunk(size int, list any) [][]any {
  60. l, err := mustChunk(size, list)
  61. if err != nil {
  62. panic(err)
  63. }
  64. return l
  65. }
  66. func mustChunk(size int, list any) ([][]any, error) {
  67. tp := reflect.TypeOf(list).Kind()
  68. switch tp {
  69. case reflect.Slice, reflect.Array:
  70. l2 := reflect.ValueOf(list)
  71. l := l2.Len()
  72. cs := int(math.Floor(float64(l-1)/float64(size)) + 1)
  73. nl := make([][]any, cs)
  74. for i := 0; i < cs; i++ {
  75. clen := size
  76. if i == cs-1 {
  77. clen = int(math.Floor(math.Mod(float64(l), float64(size))))
  78. if clen == 0 {
  79. clen = size
  80. }
  81. }
  82. nl[i] = make([]any, clen)
  83. for j := 0; j < clen; j++ {
  84. ix := i*size + j
  85. nl[i][j] = l2.Index(ix).Interface()
  86. }
  87. }
  88. return nl, nil
  89. default:
  90. return nil, fmt.Errorf("cannot chunk type %s", tp)
  91. }
  92. }
  93. func last(list any) any {
  94. l, err := mustLast(list)
  95. if err != nil {
  96. panic(err)
  97. }
  98. return l
  99. }
  100. func mustLast(list any) (any, error) {
  101. tp := reflect.TypeOf(list).Kind()
  102. switch tp {
  103. case reflect.Slice, reflect.Array:
  104. l2 := reflect.ValueOf(list)
  105. l := l2.Len()
  106. if l == 0 {
  107. return nil, nil
  108. }
  109. return l2.Index(l - 1).Interface(), nil
  110. default:
  111. return nil, fmt.Errorf("cannot find last on type %s", tp)
  112. }
  113. }
  114. func first(list any) any {
  115. l, err := mustFirst(list)
  116. if err != nil {
  117. panic(err)
  118. }
  119. return l
  120. }
  121. func mustFirst(list any) (any, error) {
  122. tp := reflect.TypeOf(list).Kind()
  123. switch tp {
  124. case reflect.Slice, reflect.Array:
  125. l2 := reflect.ValueOf(list)
  126. l := l2.Len()
  127. if l == 0 {
  128. return nil, nil
  129. }
  130. return l2.Index(0).Interface(), nil
  131. default:
  132. return nil, fmt.Errorf("cannot find first on type %s", tp)
  133. }
  134. }
  135. func rest(list any) []any {
  136. l, err := mustRest(list)
  137. if err != nil {
  138. panic(err)
  139. }
  140. return l
  141. }
  142. func mustRest(list any) ([]any, error) {
  143. tp := reflect.TypeOf(list).Kind()
  144. switch tp {
  145. case reflect.Slice, reflect.Array:
  146. l2 := reflect.ValueOf(list)
  147. l := l2.Len()
  148. if l == 0 {
  149. return nil, nil
  150. }
  151. nl := make([]any, l-1)
  152. for i := 1; i < l; i++ {
  153. nl[i-1] = l2.Index(i).Interface()
  154. }
  155. return nl, nil
  156. default:
  157. return nil, fmt.Errorf("cannot find rest on type %s", tp)
  158. }
  159. }
  160. func initial(list any) []any {
  161. l, err := mustInitial(list)
  162. if err != nil {
  163. panic(err)
  164. }
  165. return l
  166. }
  167. func mustInitial(list any) ([]any, error) {
  168. tp := reflect.TypeOf(list).Kind()
  169. switch tp {
  170. case reflect.Slice, reflect.Array:
  171. l2 := reflect.ValueOf(list)
  172. l := l2.Len()
  173. if l == 0 {
  174. return nil, nil
  175. }
  176. nl := make([]any, l-1)
  177. for i := 0; i < l-1; i++ {
  178. nl[i] = l2.Index(i).Interface()
  179. }
  180. return nl, nil
  181. default:
  182. return nil, fmt.Errorf("cannot find initial on type %s", tp)
  183. }
  184. }
  185. func sortAlpha(list any) []string {
  186. k := reflect.Indirect(reflect.ValueOf(list)).Kind()
  187. switch k {
  188. case reflect.Slice, reflect.Array:
  189. a := strslice(list)
  190. s := sort.StringSlice(a)
  191. s.Sort()
  192. return s
  193. }
  194. return []string{strval(list)}
  195. }
  196. func reverse(v any) []any {
  197. l, err := mustReverse(v)
  198. if err != nil {
  199. panic(err)
  200. }
  201. return l
  202. }
  203. func mustReverse(v any) ([]any, error) {
  204. tp := reflect.TypeOf(v).Kind()
  205. switch tp {
  206. case reflect.Slice, reflect.Array:
  207. l2 := reflect.ValueOf(v)
  208. l := l2.Len()
  209. // We do not sort in place because the incoming array should not be altered.
  210. nl := make([]any, l)
  211. for i := 0; i < l; i++ {
  212. nl[l-i-1] = l2.Index(i).Interface()
  213. }
  214. return nl, nil
  215. default:
  216. return nil, fmt.Errorf("cannot find reverse on type %s", tp)
  217. }
  218. }
  219. func compact(list any) []any {
  220. l, err := mustCompact(list)
  221. if err != nil {
  222. panic(err)
  223. }
  224. return l
  225. }
  226. func mustCompact(list any) ([]any, error) {
  227. tp := reflect.TypeOf(list).Kind()
  228. switch tp {
  229. case reflect.Slice, reflect.Array:
  230. l2 := reflect.ValueOf(list)
  231. l := l2.Len()
  232. nl := []any{}
  233. var item any
  234. for i := 0; i < l; i++ {
  235. item = l2.Index(i).Interface()
  236. if !empty(item) {
  237. nl = append(nl, item)
  238. }
  239. }
  240. return nl, nil
  241. default:
  242. return nil, fmt.Errorf("cannot compact on type %s", tp)
  243. }
  244. }
  245. func uniq(list any) []any {
  246. l, err := mustUniq(list)
  247. if err != nil {
  248. panic(err)
  249. }
  250. return l
  251. }
  252. func mustUniq(list any) ([]any, error) {
  253. tp := reflect.TypeOf(list).Kind()
  254. switch tp {
  255. case reflect.Slice, reflect.Array:
  256. l2 := reflect.ValueOf(list)
  257. l := l2.Len()
  258. dest := []any{}
  259. var item any
  260. for i := 0; i < l; i++ {
  261. item = l2.Index(i).Interface()
  262. if !inList(dest, item) {
  263. dest = append(dest, item)
  264. }
  265. }
  266. return dest, nil
  267. default:
  268. return nil, fmt.Errorf("cannot find uniq on type %s", tp)
  269. }
  270. }
  271. func inList(haystack []any, needle any) bool {
  272. for _, h := range haystack {
  273. if reflect.DeepEqual(needle, h) {
  274. return true
  275. }
  276. }
  277. return false
  278. }
  279. func without(list any, omit ...any) []any {
  280. l, err := mustWithout(list, omit...)
  281. if err != nil {
  282. panic(err)
  283. }
  284. return l
  285. }
  286. func mustWithout(list any, omit ...any) ([]any, error) {
  287. tp := reflect.TypeOf(list).Kind()
  288. switch tp {
  289. case reflect.Slice, reflect.Array:
  290. l2 := reflect.ValueOf(list)
  291. l := l2.Len()
  292. res := []any{}
  293. var item any
  294. for i := 0; i < l; i++ {
  295. item = l2.Index(i).Interface()
  296. if !inList(omit, item) {
  297. res = append(res, item)
  298. }
  299. }
  300. return res, nil
  301. default:
  302. return nil, fmt.Errorf("cannot find without on type %s", tp)
  303. }
  304. }
  305. func has(needle any, haystack any) bool {
  306. l, err := mustHas(needle, haystack)
  307. if err != nil {
  308. panic(err)
  309. }
  310. return l
  311. }
  312. func mustHas(needle any, haystack any) (bool, error) {
  313. if haystack == nil {
  314. return false, nil
  315. }
  316. tp := reflect.TypeOf(haystack).Kind()
  317. switch tp {
  318. case reflect.Slice, reflect.Array:
  319. l2 := reflect.ValueOf(haystack)
  320. var item any
  321. l := l2.Len()
  322. for i := 0; i < l; i++ {
  323. item = l2.Index(i).Interface()
  324. if reflect.DeepEqual(needle, item) {
  325. return true, nil
  326. }
  327. }
  328. return false, nil
  329. default:
  330. return false, fmt.Errorf("cannot find has on type %s", tp)
  331. }
  332. }
  333. // $list := [1, 2, 3, 4, 5]
  334. // slice $list -> list[0:5] = list[:]
  335. // slice $list 0 3 -> list[0:3] = list[:3]
  336. // slice $list 3 5 -> list[3:5]
  337. // slice $list 3 -> list[3:5] = list[3:]
  338. func slice(list any, indices ...any) any {
  339. l, err := mustSlice(list, indices...)
  340. if err != nil {
  341. panic(err)
  342. }
  343. return l
  344. }
  345. func mustSlice(list any, indices ...any) (any, error) {
  346. tp := reflect.TypeOf(list).Kind()
  347. switch tp {
  348. case reflect.Slice, reflect.Array:
  349. l2 := reflect.ValueOf(list)
  350. l := l2.Len()
  351. if l == 0 {
  352. return nil, nil
  353. }
  354. var start, end int
  355. if len(indices) > 0 {
  356. start = toInt(indices[0])
  357. }
  358. if len(indices) < 2 {
  359. end = l
  360. } else {
  361. end = toInt(indices[1])
  362. }
  363. return l2.Slice(start, end).Interface(), nil
  364. default:
  365. return nil, fmt.Errorf("list should be type of slice or array but %s", tp)
  366. }
  367. }
  368. func concat(lists ...any) any {
  369. var res []any
  370. for _, list := range lists {
  371. tp := reflect.TypeOf(list).Kind()
  372. switch tp {
  373. case reflect.Slice, reflect.Array:
  374. l2 := reflect.ValueOf(list)
  375. for i := 0; i < l2.Len(); i++ {
  376. res = append(res, l2.Index(i).Interface())
  377. }
  378. default:
  379. panic(fmt.Sprintf("cannot concat type %s as list", tp))
  380. }
  381. }
  382. return res
  383. }