mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-25 12:57:18 +00:00
Refactor Slice Utils as Variadic Functions (#3206)
* variadic approach working * transform to variadic * comments * all variadic funcs simplified and tests passing
This commit is contained in:
parent
c0627e29a8
commit
65ee6eb3af
@ -25,40 +25,54 @@ func SubsetUint64(a []uint64, b []uint64) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// IntersectionUint64 of two uint64 slices with time
|
||||
// IntersectionUint64 of any number of uint64 slices with time
|
||||
// complexity of approximately O(n) leveraging a map to
|
||||
// check for element existence off by a constant factor
|
||||
// of underlying map efficiency.
|
||||
func IntersectionUint64(a []uint64, b []uint64) []uint64 {
|
||||
set := make([]uint64, 0)
|
||||
m := make(map[uint64]bool)
|
||||
|
||||
for i := 0; i < len(a); i++ {
|
||||
m[a[i]] = true
|
||||
func IntersectionUint64(s ...[]uint64) []uint64 {
|
||||
if len(s) == 0 {
|
||||
return []uint64{}
|
||||
}
|
||||
for i := 0; i < len(b); i++ {
|
||||
if _, found := m[b[i]]; found {
|
||||
set = append(set, b[i])
|
||||
if len(s) == 1 {
|
||||
return s[0]
|
||||
}
|
||||
intersect := make([]uint64, 0)
|
||||
for i := 1; i < len(s); i++ {
|
||||
m := make(map[uint64]bool)
|
||||
for j := 0; j < len(s[i-1]); j++ {
|
||||
m[s[i-1][j]] = true
|
||||
}
|
||||
for j := 0; j < len(s[i]); j++ {
|
||||
if _, found := m[s[i][j]]; found {
|
||||
intersect = append(intersect, s[i][j])
|
||||
}
|
||||
}
|
||||
}
|
||||
return set
|
||||
return intersect
|
||||
}
|
||||
|
||||
// UnionUint64 of two uint64 slices with time
|
||||
// UnionUint64 of any number of uint64 slices with time
|
||||
// complexity of approximately O(n) leveraging a map to
|
||||
// check for element existence off by a constant factor
|
||||
// of underlying map efficiency.
|
||||
func UnionUint64(a []uint64, b []uint64) []uint64 {
|
||||
func UnionUint64(s ...[]uint64) []uint64 {
|
||||
if len(s) == 0 {
|
||||
return []uint64{}
|
||||
}
|
||||
if len(s) == 1 {
|
||||
return s[0]
|
||||
}
|
||||
set := make([]uint64, 0)
|
||||
m := make(map[uint64]bool)
|
||||
|
||||
for i := 0; i < len(a); i++ {
|
||||
m[a[i]] = true
|
||||
set = append(set, a[i])
|
||||
}
|
||||
for i := 0; i < len(b); i++ {
|
||||
if _, found := m[b[i]]; !found {
|
||||
set = append(set, b[i])
|
||||
for i := 1; i < len(s); i++ {
|
||||
for j := 0; j < len(s[i-1]); j++ {
|
||||
m[s[i-1][j]] = true
|
||||
set = append(set, s[i-1][j])
|
||||
}
|
||||
for j := 0; j < len(s[i]); j++ {
|
||||
if _, found := m[s[i][j]]; !found {
|
||||
set = append(set, s[i][j])
|
||||
}
|
||||
}
|
||||
}
|
||||
return set
|
||||
@ -106,40 +120,54 @@ func IsInUint64(a uint64, b []uint64) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IntersectionInt64 of two int64 slices with time
|
||||
// IntersectionInt64 of any number of int64 slices with time
|
||||
// complexity of approximately O(n) leveraging a map to
|
||||
// check for element existence off by a constant factor
|
||||
// of underlying map efficiency.
|
||||
func IntersectionInt64(a []int64, b []int64) []int64 {
|
||||
func IntersectionInt64(s ...[]int64) []int64 {
|
||||
if len(s) == 0 {
|
||||
return []int64{}
|
||||
}
|
||||
if len(s) == 1 {
|
||||
return s[0]
|
||||
}
|
||||
set := make([]int64, 0)
|
||||
m := make(map[int64]bool)
|
||||
|
||||
for i := 0; i < len(a); i++ {
|
||||
m[a[i]] = true
|
||||
}
|
||||
for i := 0; i < len(b); i++ {
|
||||
if _, found := m[b[i]]; found {
|
||||
set = append(set, b[i])
|
||||
for i := 1; i < len(s); i++ {
|
||||
for j := 0; j < len(s[i-1]); j++ {
|
||||
m[s[i-1][j]] = true
|
||||
}
|
||||
for j := 0; j < len(s[i]); j++ {
|
||||
if _, found := m[s[i][j]]; found {
|
||||
set = append(set, s[i][j])
|
||||
}
|
||||
}
|
||||
}
|
||||
return set
|
||||
}
|
||||
|
||||
// UnionInt64 of two int64 slices with time
|
||||
// UnionInt64 of any number of int64 slices with time
|
||||
// complexity of approximately O(n) leveraging a map to
|
||||
// check for element existence off by a constant factor
|
||||
// of underlying map efficiency.
|
||||
func UnionInt64(a []int64, b []int64) []int64 {
|
||||
func UnionInt64(s ...[]int64) []int64 {
|
||||
if len(s) == 0 {
|
||||
return []int64{}
|
||||
}
|
||||
if len(s) == 1 {
|
||||
return s[0]
|
||||
}
|
||||
set := make([]int64, 0)
|
||||
m := make(map[int64]bool)
|
||||
|
||||
for i := 0; i < len(a); i++ {
|
||||
m[a[i]] = true
|
||||
set = append(set, a[i])
|
||||
}
|
||||
for i := 0; i < len(b); i++ {
|
||||
if _, found := m[b[i]]; !found {
|
||||
set = append(set, b[i])
|
||||
for i := 1; i < len(s); i++ {
|
||||
for j := 0; j < len(s[i-1]); j++ {
|
||||
m[s[i-1][j]] = true
|
||||
set = append(set, s[i-1][j])
|
||||
}
|
||||
for j := 0; j < len(s[i]); j++ {
|
||||
if _, found := m[s[i][j]]; !found {
|
||||
set = append(set, s[i][j])
|
||||
}
|
||||
}
|
||||
}
|
||||
return set
|
||||
@ -174,44 +202,35 @@ func IsInInt64(a int64, b []int64) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IntersectionByteSlices returns the common elements between two
|
||||
// sets of byte slices.
|
||||
func IntersectionByteSlices(s1, s2 [][]byte) [][]byte {
|
||||
hash := make(map[string]bool)
|
||||
for _, e := range s1 {
|
||||
hash[string(e)] = true
|
||||
}
|
||||
inter := make([][]byte, 0)
|
||||
for _, e := range s2 {
|
||||
if hash[string(e)] {
|
||||
inter = append(inter, e)
|
||||
}
|
||||
}
|
||||
// Remove duplicates from slice.
|
||||
deduped := make([][]byte, 0)
|
||||
encountered := make(map[string]bool)
|
||||
for _, element := range inter {
|
||||
if !encountered[string(element)] {
|
||||
deduped = append(deduped, element)
|
||||
encountered[string(element)] = true
|
||||
}
|
||||
}
|
||||
return deduped
|
||||
}
|
||||
|
||||
// TotalIntersectionByteSlices takes in a set of byte slices
|
||||
// and determines the intersection of common elements across all of them,
|
||||
// returning a single slice of byte slices.
|
||||
func TotalIntersectionByteSlices(sets [][][]byte) [][]byte {
|
||||
if len(sets) == 0 {
|
||||
// IntersectionByteSlices returns the common elements between sets of byte slices.
|
||||
func IntersectionByteSlices(s ...[][]byte) [][]byte {
|
||||
if len(s) == 0 {
|
||||
return [][]byte{}
|
||||
}
|
||||
if len(sets) == 1 {
|
||||
return sets[0]
|
||||
if len(s) == 1 {
|
||||
return s[0]
|
||||
}
|
||||
intersected := IntersectionByteSlices(sets[0], sets[1])
|
||||
for i := 2; i < len(sets); i++ {
|
||||
intersected = IntersectionByteSlices(intersected, sets[i])
|
||||
inter := make([][]byte, 0)
|
||||
for i := 1; i < len(s); i++ {
|
||||
hash := make(map[string]bool)
|
||||
for _, e := range s[i-1] {
|
||||
hash[string(e)] = true
|
||||
}
|
||||
for _, e := range s[i] {
|
||||
if hash[string(e)] {
|
||||
inter = append(inter, e)
|
||||
}
|
||||
}
|
||||
tmp := make([][]byte, 0)
|
||||
// Remove duplicates from slice.
|
||||
encountered := make(map[string]bool)
|
||||
for _, element := range inter {
|
||||
if !encountered[string(element)] {
|
||||
tmp = append(tmp, element)
|
||||
encountered[string(element)] = true
|
||||
}
|
||||
}
|
||||
inter = tmp
|
||||
}
|
||||
return intersected
|
||||
return inter
|
||||
}
|
||||
|
@ -228,81 +228,69 @@ func TestIsInInt64(t *testing.T) {
|
||||
|
||||
func TestIntersectionByteSlices(t *testing.T) {
|
||||
testCases := []struct {
|
||||
a [][]byte
|
||||
b [][]byte
|
||||
input [][][]byte
|
||||
result [][]byte
|
||||
}{
|
||||
{[][]byte{{1, 2, 3}, {4, 5}}, [][]byte{{1, 2}, {4, 5}}, [][]byte{{4, 5}}},
|
||||
// Ensure duplicate elements are moved in the resulting set.
|
||||
{[][]byte{{1, 2, 3}, {4, 5}, {4, 5}}, [][]byte{{1, 2}, {4, 5}, {4, 5}}, [][]byte{{4, 5}}},
|
||||
{
|
||||
input: [][][]byte{
|
||||
{
|
||||
{1, 2, 3},
|
||||
{4, 5},
|
||||
},
|
||||
{
|
||||
{1, 2},
|
||||
{4, 5},
|
||||
},
|
||||
},
|
||||
result: [][]byte{{4, 5}},
|
||||
},
|
||||
// Ensure duplicate elements are removed in the resulting set.
|
||||
{
|
||||
input: [][][]byte{
|
||||
{
|
||||
{1, 2, 3},
|
||||
{4, 5},
|
||||
{4, 5},
|
||||
},
|
||||
{
|
||||
{1, 2},
|
||||
{4, 5},
|
||||
{4, 5},
|
||||
},
|
||||
},
|
||||
result: [][]byte{{4, 5}},
|
||||
},
|
||||
// Ensure no intersection returns an empty set.
|
||||
{[][]byte{{1, 2, 3}, {4, 5}}, [][]byte{{1, 2}}, [][]byte{}},
|
||||
{
|
||||
input: [][][]byte{
|
||||
{
|
||||
{1, 2, 3},
|
||||
{4, 5},
|
||||
},
|
||||
{
|
||||
{1, 2},
|
||||
},
|
||||
},
|
||||
result: [][]byte{},
|
||||
},
|
||||
// Intersection between A and A should return A.
|
||||
{[][]byte{{1, 2}}, [][]byte{{1, 2}}, [][]byte{{1, 2}}},
|
||||
}
|
||||
for _, tt := range testCases {
|
||||
result := IntersectionByteSlices(tt.a, tt.b)
|
||||
if !reflect.DeepEqual(result, tt.result) {
|
||||
t.Errorf("IntersectionByteSlices(%v, %v)=%v, wanted: %v",
|
||||
tt.a, tt.b, result, tt.result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTotalIntersectionByteSlices(t *testing.T) {
|
||||
testCases := []struct {
|
||||
a [][][]byte
|
||||
result [][]byte
|
||||
}{
|
||||
{
|
||||
[][][]byte{
|
||||
input: [][][]byte{
|
||||
{
|
||||
{1, 2, 3},
|
||||
{4, 5},
|
||||
{1, 2},
|
||||
},
|
||||
{
|
||||
{4, 5},
|
||||
},
|
||||
{
|
||||
{4, 5},
|
||||
{6, 7, 8},
|
||||
{9, 10, 11},
|
||||
{1, 2},
|
||||
},
|
||||
},
|
||||
[][]byte{
|
||||
{4, 5},
|
||||
},
|
||||
},
|
||||
{
|
||||
[][][]byte{
|
||||
{
|
||||
{1, 2, 3},
|
||||
{4, 5},
|
||||
},
|
||||
},
|
||||
[][]byte{
|
||||
{1, 2, 3},
|
||||
{4, 5},
|
||||
},
|
||||
},
|
||||
{
|
||||
[][][]byte{
|
||||
{
|
||||
{1, 2, 3},
|
||||
{4, 5},
|
||||
},
|
||||
{
|
||||
{6},
|
||||
},
|
||||
},
|
||||
[][]byte{},
|
||||
result: [][]byte{{1, 2}},
|
||||
},
|
||||
}
|
||||
for _, tt := range testCases {
|
||||
result := TotalIntersectionByteSlices(tt.a)
|
||||
result := IntersectionByteSlices(tt.input...)
|
||||
if !reflect.DeepEqual(result, tt.result) {
|
||||
t.Errorf("TotalIntersectionByteSlices(%v)=%v, wanted: %v",
|
||||
tt.a, result, tt.result)
|
||||
t.Errorf("IntersectionByteSlices(%v)=%v, wanted: %v",
|
||||
tt.input, result, tt.result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user