github.com/openimsdk/tools@v0.0.49/utils/datautil/datautil.go (about) 1 // Copyright © 2023 OpenIM. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package datautil 16 17 import ( 18 "github.com/jinzhu/copier" 19 "github.com/openimsdk/tools/db/pagination" 20 "github.com/openimsdk/tools/errs" 21 "github.com/openimsdk/tools/utils/jsonutil" 22 "reflect" 23 "sort" 24 ) 25 26 // SliceSubFuncs returns elements in slice a that are not present in slice b (a - b) and remove duplicates. 27 // Determine if elements are equal based on the result returned by fna(a[i]) and fnb(b[i]). 28 func SliceSubFuncs[T, V any, E comparable](a []T, b []V, fna func(i T) E, fnb func(i V) E) []T { 29 if len(b) == 0 { 30 return a 31 } 32 k := make(map[E]struct{}) 33 for i := 0; i < len(b); i++ { 34 k[fnb(b[i])] = struct{}{} 35 } 36 t := make(map[E]struct{}) 37 rs := make([]T, 0, len(a)) 38 for i := 0; i < len(a); i++ { 39 e := fna(a[i]) 40 if _, ok := t[e]; ok { 41 continue 42 } 43 if _, ok := k[e]; ok { 44 continue 45 } 46 rs = append(rs, a[i]) 47 t[e] = struct{}{} 48 } 49 return rs 50 } 51 52 // SliceSubFunc returns elements in slice a that are not present in slice b (a - b) and remove duplicates. 53 // Determine if elements are equal based on the result returned by fn. 54 func SliceSubFunc[T any, E comparable](a, b []T, fn func(i T) E) []T { 55 return SliceSubFuncs(a, b, fn, fn) 56 } 57 58 // SliceSub returns elements in slice a that are not present in slice b (a - b) and remove duplicates. 59 func SliceSub[E comparable](a, b []E) []E { 60 return SliceSubFunc(a, b, func(i E) E { return i }) 61 } 62 63 // SliceSubAny returns elements in slice a that are not present in slice b (a - b) and remove duplicates. 64 // fn is a function that converts elements of slice b to elements comparable with those in slice a. 65 func SliceSubAny[E comparable, T any](a []E, b []T, fn func(t T) E) []E { 66 return SliceSub(a, Slice(b, fn)) 67 } 68 69 // SliceSubConvertPre returns elements in slice a that are not present in slice b (a - b) and remove duplicates. 70 // fn is a function that converts elements of slice a to elements comparable with those in slice b. 71 func SliceSubConvertPre[E comparable, T any](a []T, b []E, fn func(t T) E) []T { 72 return SliceSubFuncs(a, b, fn, func(i E) E { return i }) 73 } 74 75 // SliceAnySub returns elements in slice a that are not present in slice b (a - b). 76 func SliceAnySub[E any, T comparable](a, b []E, fn func(t E) T) []E { 77 m := make(map[T]E) 78 for i := 0; i < len(b); i++ { 79 v := b[i] 80 m[fn(v)] = v 81 } 82 var es []E 83 for i := 0; i < len(a); i++ { 84 v := a[i] 85 if _, ok := m[fn(v)]; !ok { 86 es = append(es, v) 87 } 88 } 89 return es 90 } 91 92 // DistinctAny duplicate removal. 93 func DistinctAny[E any, K comparable](es []E, fn func(e E) K) []E { 94 v := make([]E, 0, len(es)) 95 tmp := map[K]struct{}{} 96 for i := 0; i < len(es); i++ { 97 t := es[i] 98 k := fn(t) 99 if _, ok := tmp[k]; !ok { 100 tmp[k] = struct{}{} 101 v = append(v, t) 102 } 103 } 104 return v 105 } 106 107 func DistinctAnyGetComparable[E any, K comparable](es []E, fn func(e E) K) []K { 108 v := make([]K, 0, len(es)) 109 tmp := map[K]struct{}{} 110 for i := 0; i < len(es); i++ { 111 t := es[i] 112 k := fn(t) 113 if _, ok := tmp[k]; !ok { 114 tmp[k] = struct{}{} 115 v = append(v, k) 116 } 117 } 118 return v 119 } 120 121 func Distinct[T comparable](ts []T) []T { 122 if len(ts) < 2 { 123 return ts 124 } else if len(ts) == 2 { 125 if ts[0] == ts[1] { 126 return ts[:1] 127 } else { 128 return ts 129 } 130 } 131 return DistinctAny(ts, func(t T) T { 132 return t 133 }) 134 } 135 136 // Delete Delete slice elements, support negative number to delete the reciprocal number 137 func Delete[E any](es []E, index ...int) []E { 138 switch len(index) { 139 case 0: 140 return es 141 case 1: 142 i := index[0] 143 if i < 0 { 144 i = len(es) + i 145 } 146 if len(es) <= i { 147 return es 148 } 149 return append(es[:i], es[i+1:]...) 150 default: 151 tmp := make(map[int]struct{}) 152 for _, i := range index { 153 if i < 0 { 154 i = len(es) + i 155 } 156 tmp[i] = struct{}{} 157 } 158 v := make([]E, 0, len(es)) 159 for i := 0; i < len(es); i++ { 160 if _, ok := tmp[i]; !ok { 161 v = append(v, es[i]) 162 } 163 } 164 return v 165 } 166 } 167 168 // DeleteAt Delete slice elements, support negative number to delete the reciprocal number 169 func DeleteAt[E any](es *[]E, index ...int) []E { 170 v := Delete(*es, index...) 171 *es = v 172 return v 173 } 174 175 // IndexAny get the index of the element 176 func IndexAny[E any, K comparable](e E, es []E, fn func(e E) K) int { 177 k := fn(e) 178 for i := 0; i < len(es); i++ { 179 if fn(es[i]) == k { 180 return i 181 } 182 } 183 return -1 184 } 185 186 // IndexOf get the index of the element 187 func IndexOf[E comparable](e E, es ...E) int { 188 return IndexAny(e, es, func(t E) E { 189 return t 190 }) 191 } 192 193 // DeleteElems delete elems in slice. 194 func DeleteElems[E comparable](es []E, delEs ...E) []E { 195 switch len(delEs) { 196 case 0: 197 return es 198 case 1: 199 for i := range es { 200 if es[i] == delEs[0] { 201 return append(es[:i], es[i+1:]...) 202 } 203 } 204 return es 205 default: 206 elMap := make(map[E]int) 207 for _, e := range delEs { 208 elMap[e]++ 209 } 210 res := make([]E, 0, len(es)) 211 for i := range es { 212 if _, ok := elMap[es[i]]; ok { 213 elMap[es[i]]-- 214 if elMap[es[i]] == 0 { 215 delete(elMap, es[i]) 216 } 217 continue 218 } 219 res = append(res, es[i]) 220 } 221 return res 222 } 223 } 224 225 // Contain Whether to include 226 func Contain[E comparable](e E, es ...E) bool { 227 return IndexOf(e, es...) >= 0 228 } 229 230 // DuplicateAny Whether there are duplicates 231 func DuplicateAny[E any, K comparable](es []E, fn func(e E) K) bool { 232 t := make(map[K]struct{}) 233 for _, e := range es { 234 k := fn(e) 235 if _, ok := t[k]; ok { 236 return true 237 } 238 t[k] = struct{}{} 239 } 240 return false 241 } 242 243 // Duplicate Whether there are duplicates 244 func Duplicate[E comparable](es []E) bool { 245 return DuplicateAny(es, func(e E) E { 246 return e 247 }) 248 } 249 250 // SliceToMapOkAny slice to map (Custom type, filter) 251 func SliceToMapOkAny[E any, K comparable, V any](es []E, fn func(e E) (K, V, bool)) map[K]V { 252 kv := make(map[K]V) 253 for i := 0; i < len(es); i++ { 254 t := es[i] 255 if k, v, ok := fn(t); ok { 256 kv[k] = v 257 } 258 } 259 return kv 260 } 261 262 // SliceToMapAny slice to map (Custom type) 263 func SliceToMapAny[E any, K comparable, V any](es []E, fn func(e E) (K, V)) map[K]V { 264 return SliceToMapOkAny(es, func(e E) (K, V, bool) { 265 k, v := fn(e) 266 return k, v, true 267 }) 268 } 269 270 // SliceToMap slice to map 271 func SliceToMap[E any, K comparable](es []E, fn func(e E) K) map[K]E { 272 return SliceToMapOkAny(es, func(e E) (K, E, bool) { 273 k := fn(e) 274 return k, e, true 275 }) 276 } 277 278 // SliceSetAny slice to map[K]struct{} 279 func SliceSetAny[E any, K comparable](es []E, fn func(e E) K) map[K]struct{} { 280 return SliceToMapAny(es, func(e E) (K, struct{}) { 281 return fn(e), struct{}{} 282 }) 283 } 284 285 func Filter[E, T any](es []E, fn func(e E) (T, bool)) []T { 286 rs := make([]T, 0, len(es)) 287 for i := 0; i < len(es); i++ { 288 e := es[i] 289 if t, ok := fn(e); ok { 290 rs = append(rs, t) 291 } 292 } 293 return rs 294 } 295 296 // Slice Converts slice types in batches 297 func Slice[E any, T any](es []E, fn func(e E) T) []T { 298 v := make([]T, len(es)) 299 for i := 0; i < len(es); i++ { 300 v[i] = fn(es[i]) 301 } 302 return v 303 } 304 305 // SliceSet slice to map[E]struct{} 306 func SliceSet[E comparable](es []E) map[E]struct{} { 307 return SliceSetAny(es, func(e E) E { 308 return e 309 }) 310 } 311 312 // HasKey get whether the map contains key 313 func HasKey[K comparable, V any](m map[K]V, k K) bool { 314 if m == nil { 315 return false 316 } 317 _, ok := m[k] 318 return ok 319 } 320 321 // Min get minimum value 322 func Min[E Ordered](e ...E) E { 323 v := e[0] 324 for _, t := range e[1:] { 325 if v > t { 326 v = t 327 } 328 } 329 return v 330 } 331 332 // Max get maximum value 333 func Max[E Ordered](e ...E) E { 334 v := e[0] 335 for _, t := range e[1:] { 336 if v < t { 337 v = t 338 } 339 } 340 return v 341 } 342 343 // Between checks if data is between left and right, excluding equality. 344 func Between[E Ordered](data, left, right E) bool { 345 return left < data && data < right 346 } 347 348 // BetweenEq checks if data is between left and right, including equality. 349 func BetweenEq[E Ordered](data, left, right E) bool { 350 return left <= data && data <= right 351 } 352 353 // BetweenLEq checks if data is between left and right, including left equality. 354 func BetweenLEq[E Ordered](data, left, right E) bool { 355 return left <= data && data < right 356 } 357 358 // BetweenREq checks if data is between left and right, including right equality. 359 func BetweenREq[E Ordered](data, left, right E) bool { 360 return left < data && data <= right 361 } 362 363 func Paginate[E any](es []E, pageNumber int, showNumber int) []E { 364 if pageNumber <= 0 { 365 return []E{} 366 } 367 if showNumber <= 0 { 368 return []E{} 369 } 370 start := (pageNumber - 1) * showNumber 371 end := start + showNumber 372 if start >= len(es) { 373 return []E{} 374 } 375 if end > len(es) { 376 end = len(es) 377 } 378 return es[start:end] 379 } 380 381 func SlicePaginate[E any](es []E, pagination pagination.Pagination) []E { 382 return Paginate(es, int(pagination.GetPageNumber()), int(pagination.GetShowNumber())) 383 } 384 385 // BothExistAny gets elements that are common in the slice (intersection) 386 func BothExistAny[E any, K comparable](es [][]E, fn func(e E) K) []E { 387 if len(es) == 0 { 388 return []E{} 389 } 390 var idx int 391 ei := make([]map[K]E, len(es)) 392 for i := 0; i < len(ei); i++ { 393 e := es[i] 394 if len(e) == 0 { 395 return []E{} 396 } 397 kv := make(map[K]E) 398 for j := 0; j < len(e); j++ { 399 t := e[j] 400 k := fn(t) 401 kv[k] = t 402 } 403 ei[i] = kv 404 if len(kv) < len(ei[idx]) { 405 idx = i 406 } 407 } 408 v := make([]E, 0, len(ei[idx])) 409 for k := range ei[idx] { 410 all := true 411 for i := 0; i < len(ei); i++ { 412 if i == idx { 413 continue 414 } 415 if _, ok := ei[i][k]; !ok { 416 all = false 417 break 418 } 419 } 420 if !all { 421 continue 422 } 423 v = append(v, ei[idx][k]) 424 } 425 return v 426 } 427 428 // BothExist Gets the common elements in the slice (intersection) 429 func BothExist[E comparable](es ...[]E) []E { 430 return BothExistAny(es, func(e E) E { 431 return e 432 }) 433 } 434 435 //func CompleteAny[K comparable, E any](ks []K, es []E, fn func(e E) K) bool { 436 // if len(ks) == 0 && len(es) == 0 { 437 // return true 438 // } 439 // kn := make(map[K]uint8) 440 // for _, e := range Distinct(ks) { 441 // kn[e]++ 442 // } 443 // for k := range SliceSetAny(es, fn) { 444 // kn[k]++ 445 // } 446 // for _, n := range kn { 447 // if n != 2 { 448 // return false 449 // } 450 // } 451 // return true 452 //} 453 454 // Complete whether a and b are equal after deduplication (ignore order) 455 func Complete[E comparable](a []E, b []E) bool { 456 return len(Single(a, b)) == 0 457 } 458 459 // Keys get map keys 460 func Keys[K comparable, V any](kv map[K]V) []K { 461 ks := make([]K, 0, len(kv)) 462 for k := range kv { 463 ks = append(ks, k) 464 } 465 return ks 466 } 467 468 // Values get map values 469 func Values[K comparable, V any](kv map[K]V) []V { 470 vs := make([]V, 0, len(kv)) 471 for k := range kv { 472 vs = append(vs, kv[k]) 473 } 474 return vs 475 } 476 477 // Sort basic type sorting 478 func Sort[E Ordered](es []E, asc bool) []E { 479 SortAny(es, func(a, b E) bool { 480 if asc { 481 return a < b 482 } else { 483 return a > b 484 } 485 }) 486 return es 487 } 488 489 // SortAny custom sort method 490 func SortAny[E any](es []E, fn func(a, b E) bool) { 491 sort.Sort(&sortSlice[E]{ 492 ts: es, 493 fn: fn, 494 }) 495 } 496 497 // If true -> a, false -> b 498 func If[T any](isa bool, a, b T) T { 499 if isa { 500 return a 501 } 502 return b 503 } 504 505 func ToPtr[T any](t T) *T { 506 return &t 507 } 508 509 // Equal Compares slices to each other (including element order) 510 func Equal[E comparable](a []E, b []E) bool { 511 if len(a) != len(b) { 512 return false 513 } 514 for i := 0; i < len(a); i++ { 515 if a[i] != b[i] { 516 return false 517 } 518 } 519 return true 520 } 521 522 // Single exists in a and does not exist in b or exists in b and does not exist in a 523 func Single[E comparable](a, b []E) []E { 524 kn := make(map[E]uint8) 525 for _, e := range Distinct(a) { 526 kn[e]++ 527 } 528 for _, e := range Distinct(b) { 529 kn[e]++ 530 } 531 v := make([]E, 0, len(kn)) 532 for k, n := range kn { 533 if n == 1 { 534 v = append(v, k) 535 } 536 } 537 return v 538 } 539 540 // Order sorts ts by es 541 func Order[E comparable, T any](es []E, ts []T, fn func(t T) E) []T { 542 if len(es) == 0 || len(ts) == 0 { 543 return ts 544 } 545 kv := make(map[E][]T) 546 for i := 0; i < len(ts); i++ { 547 t := ts[i] 548 k := fn(t) 549 kv[k] = append(kv[k], t) 550 } 551 rs := make([]T, 0, len(ts)) 552 for _, e := range es { 553 vs := kv[e] 554 delete(kv, e) 555 rs = append(rs, vs...) 556 } 557 for k := range kv { 558 rs = append(rs, kv[k]...) 559 } 560 return rs 561 } 562 563 func OrderPtr[E comparable, T any](es []E, ts *[]T, fn func(t T) E) []T { 564 *ts = Order(es, *ts, fn) 565 return *ts 566 } 567 568 func UniqueJoin(s ...string) string { 569 data, _ := jsonutil.JsonMarshal(s) 570 return string(data) 571 } 572 573 type sortSlice[E any] struct { 574 ts []E 575 fn func(a, b E) bool 576 } 577 578 func (o *sortSlice[E]) Len() int { 579 return len(o.ts) 580 } 581 582 func (o *sortSlice[E]) Less(i, j int) bool { 583 return o.fn(o.ts[i], o.ts[j]) 584 } 585 586 func (o *sortSlice[E]) Swap(i, j int) { 587 o.ts[i], o.ts[j] = o.ts[j], o.ts[i] 588 } 589 590 // Ordered types that can be sorted 591 type Ordered interface { 592 ~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | ~float32 | ~float64 | ~string 593 } 594 595 // NotNilReplace sets old to new_ when new_ is not null 596 func NotNilReplace[T any](old, new_ *T) { 597 if new_ == nil { 598 return 599 } 600 *old = *new_ 601 } 602 603 func StructFieldNotNilReplace(dest, src any) { 604 destVal := reflect.ValueOf(dest).Elem() 605 srcVal := reflect.ValueOf(src).Elem() 606 607 for i := 0; i < destVal.NumField(); i++ { 608 destField := destVal.Field(i) 609 srcField := srcVal.Field(i) 610 611 // Check if the source field is valid 612 if srcField.IsValid() { 613 // Check if the target field can be set 614 if destField.CanSet() { 615 // Handling fields of slice type 616 if destField.Kind() == reflect.Slice && srcField.Kind() == reflect.Slice { 617 elemType := destField.Type().Elem() 618 // Check if a slice element is a pointer to a structure 619 if elemType.Kind() == reflect.Ptr && elemType.Elem().Kind() == reflect.Struct { 620 // Create a new slice to store the copied elements 621 newSlice := reflect.MakeSlice(destField.Type(), srcField.Len(), srcField.Cap()) 622 for j := 0; j < srcField.Len(); j++ { 623 newElem := reflect.New(elemType.Elem()) 624 // Recursive update, retaining non-zero values 625 StructFieldNotNilReplace(newElem.Interface(), srcField.Index(j).Interface()) 626 // Checks if the field of the new element is zero-valued, and if so, preserves the value at the corresponding position in the original slice 627 for k := 0; k < newElem.Elem().NumField(); k++ { 628 if newElem.Elem().Field(k).IsZero() { 629 newElem.Elem().Field(k).Set(destField.Index(j).Elem().Field(k)) 630 } 631 } 632 newSlice.Index(j).Set(newElem) 633 } 634 destField.Set(newSlice) 635 } else { 636 destField.Set(srcField) 637 } 638 } else { 639 // For non-sliced fields, update the source field if it is non-zero, otherwise keep the original value 640 if !srcField.IsZero() { 641 destField.Set(srcField) 642 } 643 } 644 } 645 } 646 } 647 } 648 649 func Batch[T any, V any](fn func(T) V, ts []T) []V { 650 if ts == nil { 651 return nil 652 } 653 res := make([]V, 0, len(ts)) 654 for i := range ts { 655 res = append(res, fn(ts[i])) 656 } 657 return res 658 } 659 660 func InitSlice[T any](val *[]T) { 661 if val != nil && *val == nil { 662 *val = []T{} 663 } 664 } 665 666 func InitMap[K comparable, V any](val *map[K]V) { 667 if val != nil && *val == nil { 668 *val = map[K]V{} 669 } 670 } 671 672 func GetSwitchFromOptions(Options map[string]bool, key string) (result bool) { 673 if Options == nil { 674 return true 675 } 676 if flag, ok := Options[key]; !ok || flag { 677 return true 678 } 679 return false 680 } 681 682 func SetSwitchFromOptions(options map[string]bool, key string, value bool) { 683 if options == nil { 684 options = make(map[string]bool, 5) 685 } 686 options[key] = value 687 } 688 689 // copy a by b b->a 690 func CopyStructFields(a any, b any, fields ...string) (err error) { 691 return copier.Copy(a, b) 692 } 693 694 func CopySlice[T any](a []T) []T { 695 ns := make([]T, len(a)) 696 copy(ns, a) 697 return ns 698 } 699 700 func GetElemByIndex(array []int, index int) (int, error) { 701 if index < 0 || index >= len(array) { 702 return 0, errs.New("index out of range", "index", index, "array", array).Wrap() 703 } 704 705 return array[index], nil 706 }