From 5d8a72a8c08a407bcc69edfc0c5372f84525605f Mon Sep 17 00:00:00 2001 From: OpenIM-Gordon <1432970085@qq.com> Date: Thu, 26 Dec 2024 16:56:42 +0800 Subject: [PATCH] feat: add intersection func. (#187) * optimization: slice sub. * fix: rpc logger add more detail info. * feat: add msg gateway error. * refactor: separate functions with error containing message and error with only stack trace. * feat: add stdout and stderr info. * feat: add strings and sql log. * feat: add copy function. * feat: add strings function. * feat: add strings function. * feat: add strings function. * feat: print version filed. * fix: version update. * refactor: change go mod name. * refactor: change go mod name. * refactor: change go mod name. * refactor: log change. * refactor: log change. * refactor: log change. * fix: log kv do not print origin pointer. * feat: log add panic level. * feat: add intersection func. --- utils/datautil/datautil.go | 44 ++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/utils/datautil/datautil.go b/utils/datautil/datautil.go index 4117031..889af46 100644 --- a/utils/datautil/datautil.go +++ b/utils/datautil/datautil.go @@ -15,14 +15,16 @@ package datautil import ( - "github.com/jinzhu/copier" - "github.com/openimsdk/tools/db/pagination" - "github.com/openimsdk/tools/errs" - "github.com/openimsdk/tools/utils/jsonutil" "math/rand" "reflect" "sort" "time" + + "github.com/jinzhu/copier" + + "github.com/openimsdk/tools/db/pagination" + "github.com/openimsdk/tools/errs" + "github.com/openimsdk/tools/utils/jsonutil" ) // SliceSubFuncs returns elements in slice a that are not present in slice b (a - b) and remove duplicates. @@ -51,6 +53,40 @@ func SliceSubFuncs[T, V any, E comparable](a []T, b []V, fna func(i T) E, fnb fu return rs } +// SliceIntersectFuncs returns the intersection (a ∩ b) of slices a and b, removing duplicates. +// The equality of elements is determined by the custom functions fna and fnb provided for each slice. +func SliceIntersectFuncs[T, V any, E comparable](a []T, b []V, fna func(i T) E, fnb func(i V) E) []T { + // If b is empty, return an empty slice + if len(b) == 0 { + return nil + } + + // Map the elements of b to a set for fast lookup + k := make(map[E]struct{}) + for _, item := range b { + k[fnb(item)] = struct{}{} + } + + // Create a slice to store the intersection result + rs := make([]T, 0, len(a)) + // Map for deduplication + t := make(map[E]struct{}) + + // Iterate over slice a and find the common elements with b + for _, item := range a { + // Get the comparison value of the element from slice a + e := fna(item) + // If the element exists in both a and b, and hasn't been added yet, add it to the result + if _, ok := k[e]; ok && t[e] == struct{}{} { + rs = append(rs, item) + t[e] = struct{}{} + } + } + + // Return the intersection slice + return rs +} + // SliceSubFunc returns elements in slice a that are not present in slice b (a - b) and remove duplicates. // Determine if elements are equal based on the result returned by fn. func SliceSubFunc[T any, E comparable](a, b []T, fn func(i T) E) []T {