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  }