Skip to content

Commit 25231be

Browse files
committed
Add back non-generics Stream/Set/StreamSet to use interface{}(as key/value) (xxxxForInterface naming)
1 parent 5a35fcb commit 25231be

File tree

6 files changed

+1418
-3
lines changed

6 files changed

+1418
-3
lines changed

fp.go

Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,34 @@ func Distinct[T comparable](list ...T) []T {
334334
return result
335335
}
336336

337+
// DistinctForInterface removes duplicates.
338+
//
339+
// Example
340+
// list := []interface{}{8, 2, 8, 0, 2, 0}
341+
// DistinctForInterface(list...) // returns [8, 2, 0]
342+
func DistinctForInterface(list ...interface{}) []interface{} {
343+
// Keep order
344+
resultIndex := 0
345+
maxLen := len(list)
346+
result := make([]interface{}, maxLen)
347+
if maxLen > 0 {
348+
s := make(map[interface{}]bool)
349+
350+
for _, v := range list {
351+
if !s[v] {
352+
result[resultIndex] = v
353+
s[v] = true
354+
355+
resultIndex++
356+
}
357+
}
358+
359+
return result[:resultIndex]
360+
}
361+
362+
return result
363+
}
364+
337365
// DistinctRandom removes duplicates.(RandomOrder)
338366
func DistinctRandom[T comparable](list ...T) []T {
339367
s := SliceToMap(true, list...)
@@ -522,6 +550,20 @@ func Exists[T comparable](input T, list ...T) bool {
522550
return false
523551
}
524552

553+
// ExistsForInterface checks if given item exists in the list
554+
//
555+
// Example:
556+
// ExistsForInterface(8, 8, 2, 10, 4) // Returns true
557+
// ExistsForInterface(8) // Returns false
558+
func ExistsForInterface(input interface{}, list ...interface{}) bool {
559+
for _, v := range list {
560+
if v == input {
561+
return true
562+
}
563+
}
564+
return false
565+
}
566+
525567
// Intersection return a set that is the intersection of the input sets
526568
// repeated value within list parameter will be ignored
527569
func Intersection[T comparable](inputList ...[]T) []T {
@@ -571,6 +613,55 @@ func Intersection[T comparable](inputList ...[]T) []T {
571613
return newList
572614
}
573615

616+
// IntersectionForInterface return a set that is the intersection of the input sets
617+
// repeated value within list parameter will be ignored
618+
func IntersectionForInterface(inputList ...[]interface{}) []interface{} {
619+
inputLen := len(inputList)
620+
if inputList == nil {
621+
return make([]interface{}, 0)
622+
}
623+
624+
if inputLen == 1 {
625+
resultMap := make(map[interface{}]interface{}, len(inputList[0]))
626+
var newList []interface{}
627+
for i := 0; i < len(inputList[0]); i++ {
628+
_, ok := resultMap[inputList[0][i]]
629+
if !ok {
630+
newList = append(newList, inputList[0][i])
631+
resultMap[inputList[0][i]] = true
632+
}
633+
}
634+
return newList
635+
}
636+
637+
resultMap := make(map[interface{}]interface{})
638+
var newList []interface{}
639+
// 1st loop iterates items in 1st array
640+
// 2nd loop iterates all the rest of the arrays
641+
// 3rd loop iterates items in the rest of the arrays
642+
for i := 0; i < len(inputList[0]); i++ {
643+
644+
matchCount := 0
645+
for j := 1; j < inputLen; j++ {
646+
for _, v := range inputList[j] {
647+
// compare every items in 1st array to every items in the rest of the arrays
648+
if inputList[0][i] == v {
649+
matchCount++
650+
break
651+
}
652+
}
653+
}
654+
if matchCount == inputLen-1 {
655+
_, ok := resultMap[inputList[0][i]]
656+
if !ok {
657+
newList = append(newList, inputList[0][i])
658+
resultMap[inputList[0][i]] = true
659+
}
660+
}
661+
}
662+
return newList
663+
}
664+
574665
// IntersectionMapByKey return a set that is the intersection of the input sets
575666
func IntersectionMapByKey[T comparable, R any](inputList ...map[T]R) map[T]R {
576667
inputLen := len(inputList)
@@ -606,6 +697,41 @@ func IntersectionMapByKey[T comparable, R any](inputList ...map[T]R) map[T]R {
606697
return resultMap
607698
}
608699

700+
// IntersectionMapByKeyForInterface return a set that is the intersection of the input sets
701+
func IntersectionMapByKeyForInterface[R any](inputList ...map[interface{}]R) map[interface{}]R {
702+
inputLen := len(inputList)
703+
704+
if inputLen == 0 {
705+
return make(map[interface{}]R)
706+
}
707+
708+
if inputLen == 1 {
709+
resultMap := make(map[interface{}]R, len(inputList[0]))
710+
for k, v := range inputList[0] {
711+
resultMap[k] = v
712+
}
713+
return resultMap
714+
}
715+
716+
resultMap := make(map[interface{}]R)
717+
countMap := make(map[interface{}]int)
718+
for _, mapItem := range inputList {
719+
for k, v := range mapItem {
720+
_, exists := resultMap[k]
721+
if !exists {
722+
resultMap[k] = v
723+
}
724+
countMap[k]++
725+
}
726+
}
727+
for k, v := range countMap {
728+
if v < inputLen {
729+
delete(resultMap, k)
730+
}
731+
}
732+
return resultMap
733+
}
734+
609735
// Minus all of set1 but not in set2
610736
func Minus[T comparable](set1, set2 []T) []T {
611737
resultIndex := 0
@@ -624,6 +750,24 @@ func Minus[T comparable](set1, set2 []T) []T {
624750
return result[:resultIndex]
625751
}
626752

753+
// MinusForInterface all of set1 but not in set2
754+
func MinusForInterface(set1, set2 []interface{}) []interface{} {
755+
resultIndex := 0
756+
maxLen := len(set1)
757+
result := make([]interface{}, maxLen)
758+
set2Map := SliceToMapForInterface(true, set2...)
759+
760+
for _, item := range set1 {
761+
_, exists := set2Map[item]
762+
if !exists {
763+
result[resultIndex] = item
764+
resultIndex++
765+
}
766+
}
767+
768+
return result[:resultIndex]
769+
}
770+
627771
// MinusMapByKey all of set1 but not in set2
628772
func MinusMapByKey[T comparable, R any](set1, set2 map[T]R) map[T]R {
629773
resultMap := make(map[T]R, len(set1))
@@ -649,6 +793,17 @@ func Keys[T comparable, R any](m map[T]R) []T {
649793
return keys
650794
}
651795

796+
// KeysForInterface returns a slice of map's keys
797+
func KeysForInterface[R any](m map[interface{}]R) []interface{} {
798+
keys := make([]interface{}, len(m))
799+
i := 0
800+
for k := range m {
801+
keys[i] = k
802+
i++
803+
}
804+
return keys
805+
}
806+
652807
// Values returns a slice of map's values
653808
func Values[T comparable, R any](m map[T]R) []R {
654809
keys := make([]R, len(m))
@@ -660,6 +815,17 @@ func Values[T comparable, R any](m map[T]R) []R {
660815
return keys
661816
}
662817

818+
// ValuesForInterface returns a slice of map's values
819+
func ValuesForInterface[R any](m map[interface{}]R) []R {
820+
keys := make([]R, len(m))
821+
i := 0
822+
for _, v := range m {
823+
keys[i] = v
824+
i++
825+
}
826+
return keys
827+
}
828+
663829
// Max returns max item from the list.
664830
// Return 0 if the list is either empty or nil
665831
func Max[T Numeric](list ...T) T {
@@ -742,6 +908,39 @@ func Merge[T comparable, R any](map1, map2 map[T]R) map[T]R {
742908
return newMap
743909
}
744910

911+
// MergeForInterface takes two inputs: map[T]R and map[T]R and merge two maps and returns a new map[T]R.
912+
func MergeForInterface[R any](map1, map2 map[interface{}]R) map[interface{}]R {
913+
if map1 == nil && map2 == nil {
914+
return map[interface{}]R{}
915+
}
916+
917+
newMap := make(map[interface{}]R, len(map1)+len(map2))
918+
919+
if map1 == nil {
920+
for k, v := range map2 {
921+
newMap[k] = v
922+
}
923+
return newMap
924+
}
925+
926+
if map2 == nil {
927+
for k, v := range map1 {
928+
newMap[k] = v
929+
}
930+
return newMap
931+
}
932+
933+
for k, v := range map1 {
934+
newMap[k] = v
935+
}
936+
937+
for k, v := range map2 {
938+
newMap[k] = v
939+
}
940+
941+
return newMap
942+
}
943+
745944
// IsNeg Returns true if num is less than zero, else false
746945
func IsNeg[T Numeric](v T) bool {
747946
if v < 0 {
@@ -977,12 +1176,45 @@ func IsSubset[T comparable](list1, list2 []T) bool {
9771176
return true
9781177
}
9791178

1179+
// IsSubsetForInterface returns true or false by checking if set1 is a subset of set2
1180+
// repeated value within list parameter will be ignored
1181+
func IsSubsetForInterface(list1, list2 []interface{}) bool {
1182+
if list1 == nil || len(list1) == 0 || list2 == nil || len(list2) == 0 {
1183+
return false
1184+
}
1185+
1186+
resultMap := make(map[interface{}]interface{})
1187+
for i := 0; i < len(list1); i++ {
1188+
_, ok := resultMap[list1[i]]
1189+
if !ok {
1190+
found := false
1191+
resultMap[list1[i]] = true
1192+
for j := 0; j < len(list2); j++ {
1193+
if list1[i] == list2[j] {
1194+
found = true
1195+
break
1196+
}
1197+
}
1198+
if !found {
1199+
return false
1200+
}
1201+
}
1202+
}
1203+
return true
1204+
}
1205+
9801206
// IsSuperset returns true or false by checking if set1 is a superset of set2
9811207
// repeated value within list parameter will be ignored
9821208
func IsSuperset[T comparable](list1, list2 []T) bool {
9831209
return IsSubset(list2, list1)
9841210
}
9851211

1212+
// IsSupersetForInterface returns true or false by checking if set1 is a superset of set2
1213+
// repeated value within list parameter will be ignored
1214+
func IsSupersetForInterface(list1, list2 []interface{}) bool {
1215+
return IsSubsetForInterface(list2, list1)
1216+
}
1217+
9861218
// IsSubsetMapByKey returns true or false by checking if set1 is a subset of set2
9871219
func IsSubsetMapByKey[T comparable, R any](item1, item2 map[T]R) bool {
9881220
if item1 == nil || len(item1) == 0 || item2 == nil || len(item2) == 0 {
@@ -998,11 +1230,31 @@ func IsSubsetMapByKey[T comparable, R any](item1, item2 map[T]R) bool {
9981230
return true
9991231
}
10001232

1233+
// IsSubsetMapByKeyForInterface returns true or false by checking if set1 is a subset of set2
1234+
func IsSubsetMapByKeyForInterface[R any](item1, item2 map[interface{}]R) bool {
1235+
if item1 == nil || len(item1) == 0 || item2 == nil || len(item2) == 0 {
1236+
return false
1237+
}
1238+
1239+
for k1 := range item1 {
1240+
_, found := item2[k1]
1241+
if !found {
1242+
return false
1243+
}
1244+
}
1245+
return true
1246+
}
1247+
10011248
// IsSupersetMapByKey returns true or false by checking if set1 is a superset of set2
10021249
func IsSupersetMapByKey[T comparable, R any](item1, item2 map[T]R) bool {
10031250
return IsSubsetMapByKey(item2, item1)
10041251
}
10051252

1253+
// IsSupersetMapByKeyForInterface returns true or false by checking if set1 is a superset of set2
1254+
func IsSupersetMapByKeyForInterface[R any](item1, item2 map[interface{}]R) bool {
1255+
return IsSubsetMapByKeyForInterface(item2, item1)
1256+
}
1257+
10061258
// Take returns the first n elements of the slice
10071259
func Take[T any](count int, list ...T) []T {
10081260
if count >= len(list) || count <= 0 {
@@ -1214,6 +1466,20 @@ func DuplicateMap[T comparable, R any](input map[T]R) map[T]R {
12141466
return make(map[T]R)
12151467
}
12161468

1469+
// DuplicateMapForInterface Return a new Map
1470+
func DuplicateMapForInterface[R any](input map[interface{}]R) map[interface{}]R {
1471+
if len(input) > 0 {
1472+
newOne := make(map[interface{}]R, len(input))
1473+
for k, v := range input {
1474+
newOne[k] = v
1475+
}
1476+
1477+
return newOne
1478+
}
1479+
1480+
return make(map[interface{}]R)
1481+
}
1482+
12171483
// IsNil Check is it nil
12181484
func IsNil(obj interface{}) bool {
12191485
val := reflect.ValueOf(obj)
@@ -1255,6 +1521,17 @@ func SliceToMap[T comparable, R any](defaultValue R, input ...T) map[T]R {
12551521
return resultMap
12561522
}
12571523

1524+
// SliceToMapForInterface Return Slice of varargs
1525+
func SliceToMapForInterface[R any](defaultValue R, input ...interface{}) map[interface{}]R {
1526+
resultMap := make(map[interface{}]R)
1527+
for _, key := range input {
1528+
if _, ok := resultMap[key]; !ok {
1529+
resultMap[key] = defaultValue
1530+
}
1531+
}
1532+
return resultMap
1533+
}
1534+
12581535
// MakeNumericReturnForVariadicParamReturnBool1 Make Numeric 1 bool Return (for compose() general fp functions simply)
12591536
func MakeNumericReturnForVariadicParamReturnBool1[T any, R Numeric](fn func(...T) bool) func(...T) []R {
12601537
return func(args ...T) []R {

0 commit comments

Comments
 (0)