pax_global_header00006660000000000000000000000064136456470530014527gustar00rootroot0000000000000052 comment=6717c9f060852e9073291f2cdac591dad945f1db arrayOperations-0.2.6/000077500000000000000000000000001364564705300147165ustar00rootroot00000000000000arrayOperations-0.2.6/.gitignore000066400000000000000000000000261364564705300167040ustar00rootroot00000000000000coverage.out .DS_StorearrayOperations-0.2.6/.travis.yml000066400000000000000000000020111364564705300170210ustar00rootroot00000000000000language: go go: - tip env: global: secure: F6/r3XubO2d2QiDvCKqf1N/99J+Iiv3kHUM/S3MPz0hW95PDxL4p2n3iSRvOP+slDTqBgL2gxKwniOFTfZdwSLZDgH505+BjWxlLXYByVeBcazr1KTDHTg/t7FA0p4ZaT+6cCu404qRreevR1Fbkuf7y2aYVBaPN7Jdnx8YVLIcYVx6emGm4SQYk1//9XBMXbw02KdQ24+wmapos0Vo6cF3FWdXxl9WRBCZ2nxopAEKnoOB0pETWp+xiokABLzHI2IV++ThBiiXT3CHV75WwcSuGnW6KV+NXaQ0H1X9SrupwdCW2InGfatPjkJ+Y+H7bngYQp4LRPhNp8a/0XRKa2nFtae6mC+UMkyBA9hH5xwQfsCtG42RJbeh6EitN0lDSl9mF2lSZVIJ0EbTKds4aCBQrI0k8hIRH1NJcQY5NFw3WZifOB0vNZuGp6vQMNi9DwX8UNr1ffXtS9vbBB+sdT46fFU70Tuh3wzY97jfHFNyBX6cHlpp3/vpdT7a4cv7YRG8+6t2PquYrsiRHax8aqwWdn/rjURuN8ZwIZ3fPot9RdxLyumfnNS9mowvZm38l1SjM4ACWbVQvJQHvYmsSnGXEWY4oWaG9S7UnhEZF4VxP7PaQTAV9eKQEkr8gL49LinW34IYUxkapfUf2ytLWIWCi5VnW1ZMr2YhRRlZJK+k= install: - go get golang.org/x/tools/cmd/cover - go get github.com/mattn/goveralls script: - go test -v -covermode=count -coverprofile=coverage.out - $(go env GOPATH | awk 'BEGIN{FS=":"} {print $1}')/bin/goveralls -coverprofile=coverage.out -service=travis-ci -repotoken=$COVERALLS_TOKEN arrayOperations-0.2.6/LICENSE000066400000000000000000000020661364564705300157270ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2015 Adam Hanna Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. arrayOperations-0.2.6/README.md000066400000000000000000000065761364564705300162130ustar00rootroot00000000000000[![Build Status](https://travis-ci.org/adam-hanna/arrayOperations.svg?branch=master)](https://travis-ci.org/adam-hanna/arrayOperations) [![Coverage Status](https://coveralls.io/repos/github/adam-hanna/arrayOperations/badge.svg?branch=master)](https://coveralls.io/github/adam-hanna/arrayOperations?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/adam-hanna/arrayOperations)](https://goreportcard.com/report/github.com/adam-hanna/arrayOperations) [![GoDoc](https://godoc.org/github.com/adam-hanna/arrayOperations?status.svg)](https://godoc.org/github.com/adam-hanna/arrayOperations) # arrayOperations Small library for performing union, intersect, difference and distinct operations on slices in goLang I don't promise that these are optimized (not even close!), but they work :) ## Quickstart ~~~ go var a = []int{1, 1, 2, 3} var b = []int{2, 4} z, ok := Difference(a, b) if !ok { fmt.Println("Cannot find difference") } slice, ok := z.Interface().([]int) if !ok { fmt.Println("Cannot convert to slice") } fmt.Println(slice, reflect.TypeOf(slice)) // [1, 3, 4] []int ~~~ ## API ### [Difference](https://godoc.org/github.com/adam-hanna/arrayOperations#Difference) ~~~ go func Difference(arrs ...interface{}) (reflect.Value, bool) ~~~ Difference returns a slice of values that are only present in one of the input slices [1, 2, 2, 4, 6] & [2, 4, 5] >> [1, 5, 6] [1, 1, 3, 4, 5, 6] >> [1, 3, 4, 5, 6] ~~~ go // EXAMPLE var a = []int{1, 1, 2, 3} var b = []int{2, 4} z, ok := Difference(a, b) if !ok { fmt.Println("Cannot find difference") } slice, ok := z.Interface().([]int) if !ok { fmt.Println("Cannot convert to slice") } fmt.Println(slice, reflect.TypeOf(slice)) // [1, 3, 4] []int ~~~ ### [Distinct](https://godoc.org/github.com/adam-hanna/arrayOperations#Distinct) ~~~ go func Distinct(arr interface{}) (reflect.Value, bool) ~~~ Distinct returns the unique vals of a slice [1, 1, 2, 3] >> [1, 2, 3] ~~~ go // EXAMPLE var a = []int{1, 1, 2, 3} z, ok := Distinct(a) if !ok { fmt.Println("Cannot find distinct") } slice, ok := z.Interface().([]int) if !ok { fmt.Println("Cannot convert to slice") } fmt.Println(slice, reflect.TypeOf(slice)) // [1, 2, 3] []int ~~~ ### [Intersect](https://godoc.org/github.com/adam-hanna/arrayOperations#Intersect) ~~~ go func Intersect(arrs ...interface{}) (reflect.Value, bool) ~~~ Intersect returns a slice of values that are present in all of the input slices [1, 1, 3, 4, 5, 6] & [2, 3, 6] >> [3, 6] [1, 1, 3, 4, 5, 6] >> [1, 3, 4, 5, 6] ~~~ go // EXAMPLE var a = []int{1, 1, 2, 3} var b = []int{2, 4} z, ok := Intersect(a, b) if !ok { fmt.Println("Cannot find intersect") } slice, ok := z.Interface().([]int) if !ok { fmt.Println("Cannot convert to slice") } fmt.Println(slice, reflect.TypeOf(slice)) // [2] []int ~~~ ### [Union](https://godoc.org/github.com/adam-hanna/arrayOperations#Union) ~~~ go func Union(arrs ...interface{}) (reflect.Value, bool) ~~~ Union returns a slice that contains the unique values of all the input slices [1, 2, 2, 4, 6] & [2, 4, 5] >> [1, 2, 4, 5, 6] [1, 1, 3, 4, 5, 6] >> [1, 3, 4, 5, 6] ~~~ go // EXAMPLE var a = []int{1, 1, 2, 3} var b = []int{2, 4} z, ok := Union(a, b) if !ok { fmt.Println("Cannot find union") } slice, ok := z.Interface().([]int) if !ok { fmt.Println("Cannot convert to slice") } fmt.Println(slice, reflect.TypeOf(slice)) // [1, 2, 3, 4] []int ~~~ ## License MIT arrayOperations-0.2.6/arrayOperations.go000066400000000000000000000427511364564705300204400ustar00rootroot00000000000000package arrayOperations import ( "reflect" ) // Distinct returns the unique vals of a slice // // [1, 1, 2, 3] >> [1, 2, 3] func Distinct(arr interface{}) (reflect.Value, bool) { // create a slice from our input interface slice, ok := takeArg(arr, reflect.Slice) if !ok { return reflect.Value{}, ok } // put the values of our slice into a map // the key's of the map will be the slice's unique values c := slice.Len() m := make(map[interface{}]bool) for i := 0; i < c; i++ { m[slice.Index(i).Interface()] = true } mapLen := len(m) // create the output slice and populate it with the map's keys out := reflect.MakeSlice(reflect.TypeOf(arr), mapLen, mapLen) i := 0 for k := range m { v := reflect.ValueOf(k) o := out.Index(i) o.Set(v) i++ } return out, ok } // Intersect returns a slice of values that are present in all of the input slices // // [1, 1, 3, 4, 5, 6] & [2, 3, 6] >> [3, 6] // // [1, 1, 3, 4, 5, 6] >> [1, 3, 4, 5, 6] func Intersect(arrs ...interface{}) (reflect.Value, bool) { // create a map to count all the instances of the slice elems arrLength := len(arrs) var kind reflect.Kind var kindHasBeenSet bool tempMap := make(map[interface{}]int) for _, arg := range arrs { tempArr, ok := Distinct(arg) if !ok { return reflect.Value{}, ok } // check to be sure the type hasn't changed if kindHasBeenSet && tempArr.Len() > 0 && tempArr.Index(0).Kind() != kind { return reflect.Value{}, false } if tempArr.Len() > 0 { kindHasBeenSet = true kind = tempArr.Index(0).Kind() } c := tempArr.Len() for idx := 0; idx < c; idx++ { // how many times have we encountered this elem? if _, ok := tempMap[tempArr.Index(idx).Interface()]; ok { tempMap[tempArr.Index(idx).Interface()]++ } else { tempMap[tempArr.Index(idx).Interface()] = 1 } } } // find the keys equal to the length of the input args numElems := 0 for _, v := range tempMap { if v == arrLength { numElems++ } } out := reflect.MakeSlice(reflect.TypeOf(arrs[0]), numElems, numElems) i := 0 for key, val := range tempMap { if val == arrLength { v := reflect.ValueOf(key) o := out.Index(i) o.Set(v) i++ } } return out, true } // Union returns a slice that contains the unique values of all the input slices // // [1, 2, 2, 4, 6] & [2, 4, 5] >> [1, 2, 4, 5, 6] // // [1, 1, 3, 4, 5, 6] >> [1, 3, 4, 5, 6] func Union(arrs ...interface{}) (reflect.Value, bool) { // create a temporary map to hold the contents of the arrays tempMap := make(map[interface{}]uint8) var kind reflect.Kind var kindHasBeenSet bool // write the contents of the arrays as keys to the map. The map values don't matter for _, arg := range arrs { tempArr, ok := Distinct(arg) if !ok { return reflect.Value{}, ok } // check to be sure the type hasn't changed if kindHasBeenSet && tempArr.Len() > 0 && tempArr.Index(0).Kind() != kind { return reflect.Value{}, false } if tempArr.Len() > 0 { kindHasBeenSet = true kind = tempArr.Index(0).Kind() } c := tempArr.Len() for idx := 0; idx < c; idx++ { tempMap[tempArr.Index(idx).Interface()] = 0 } } // the map keys are now unique instances of all of the array contents mapLen := len(tempMap) out := reflect.MakeSlice(reflect.TypeOf(arrs[0]), mapLen, mapLen) i := 0 for key := range tempMap { v := reflect.ValueOf(key) o := out.Index(i) o.Set(v) i++ } return out, true } // Difference returns a slice of values that are only present in one of the input slices // // [1, 2, 2, 4, 6] & [2, 4, 5] >> [1, 5, 6] // // [1, 1, 3, 4, 5, 6] >> [1, 3, 4, 5, 6] func Difference(arrs ...interface{}) (reflect.Value, bool) { // create a temporary map to hold the contents of the arrays tempMap := make(map[interface{}]int) var kind reflect.Kind var kindHasBeenSet bool for _, arg := range arrs { tempArr, ok := Distinct(arg) if !ok { return reflect.Value{}, ok } // check to be sure the type hasn't changed if kindHasBeenSet && tempArr.Len() > 0 && tempArr.Index(0).Kind() != kind { return reflect.Value{}, false } if tempArr.Len() > 0 { kindHasBeenSet = true kind = tempArr.Index(0).Kind() } c := tempArr.Len() for idx := 0; idx < c; idx++ { // how many times have we encountered this elem? if _, ok := tempMap[tempArr.Index(idx).Interface()]; ok { tempMap[tempArr.Index(idx).Interface()]++ } else { tempMap[tempArr.Index(idx).Interface()] = 1 } } } // write the final val of the diffMap to an array and return numElems := 0 for _, v := range tempMap { if v == 1 { numElems++ } } out := reflect.MakeSlice(reflect.TypeOf(arrs[0]), numElems, numElems) i := 0 for key, val := range tempMap { if val == 1 { v := reflect.ValueOf(key) o := out.Index(i) o.Set(v) i++ } } return out, true } func takeArg(arg interface{}, kind reflect.Kind) (val reflect.Value, ok bool) { val = reflect.ValueOf(arg) if val.Kind() == kind { ok = true } return } /* *************************************************************** * * THE SECTIONS BELOW ARE DEPRECATED * /* *************************************************************** */ /* *************************************************************** * * THIS SECTION IS FOR STRINGS * /* *************************************************************** */ // IntersectString finds the intersection of two arrays. // // Deprecated: use Intersect instead. func IntersectString(args ...[]string) []string { // create a map to count all the instances of the strings arrLength := len(args) tempMap := make(map[string]int) for _, arg := range args { tempArr := DistinctString(arg) for idx := range tempArr { // how many times have we encountered this elem? if _, ok := tempMap[tempArr[idx]]; ok { tempMap[tempArr[idx]]++ } else { tempMap[tempArr[idx]] = 1 } } } // find the keys equal to the length of the input args tempArray := make([]string, 0) for key, val := range tempMap { if val == arrLength { tempArray = append(tempArray, key) } } return tempArray } // IntersectStringArr finds the intersection of two arrays using a multidimensional array as inputs // // Deprecated: use Intersect instead. func IntersectStringArr(arr [][]string) []string { // create a map to count all the instances of the strings arrLength := len(arr) tempMap := make(map[string]int) for idx1 := range arr { tempArr := DistinctString(arr[idx1]) for idx2 := range tempArr { // how many times have we encountered this elem? if _, ok := tempMap[tempArr[idx2]]; ok { tempMap[tempArr[idx2]]++ } else { tempMap[tempArr[idx2]] = 1 } } } // find the keys equal to the length of the input args tempArray := make([]string, 0) for key, val := range tempMap { if val == arrLength { tempArray = append(tempArray, key) } } return tempArray } // UnionString finds the union of two arrays. // // Deprecated: use Union instead. func UnionString(args ...[]string) []string { // create a temporary map to hold the contents of the arrays tempMap := make(map[string]uint8) // write the contents of the arrays as keys to the map. The map values don't matter for _, arg := range args { for idx := range arg { tempMap[arg[idx]] = 0 } } // the map keys are now unique instances of all of the array contents tempArray := make([]string, 0) for key := range tempMap { tempArray = append(tempArray, key) } return tempArray } // UnionStringArr finds the union of two arrays using a multidimensional array as inputs // // Deprecated: use Union instead. func UnionStringArr(arr [][]string) []string { // create a temporary map to hold the contents of the arrays tempMap := make(map[string]uint8) // write the contents of the arrays as keys to the map. The map values don't matter for idx1 := range arr { for idx2 := range arr[idx1] { tempMap[arr[idx1][idx2]] = 0 } } // the map keys are now unique instances of all of the array contents tempArray := make([]string, 0) for key := range tempMap { tempArray = append(tempArray, key) } return tempArray } // DifferenceString finds the difference of two arrays. // // Deprecated: use Difference instead. func DifferenceString(args ...[]string) []string { // create a temporary map to hold the contents of the arrays tempMap := make(map[string]int) for _, arg := range args { tempArr := DistinctString(arg) for idx := range tempArr { // how many times have we encountered this elem? if _, ok := tempMap[tempArr[idx]]; ok { tempMap[tempArr[idx]]++ } else { tempMap[tempArr[idx]] = 1 } } } // write the final val of the diffMap to an array and return tempArray := make([]string, 0) for key, val := range tempMap { if val == 1 { tempArray = append(tempArray, key) } } return tempArray } // DifferenceStringArr finds the difference of two arrays using a multidimensional array as inputs // // Deprecated: use Difference instead. func DifferenceStringArr(arr [][]string) []string { // create a temporary map to hold the contents of the arrays tempMap := make(map[string]int) for idx1 := range arr { tempArr := DistinctString(arr[idx1]) for idx2 := range tempArr { // how many times have we encountered this elem? if _, ok := tempMap[tempArr[idx2]]; ok { tempMap[tempArr[idx2]]++ } else { tempMap[tempArr[idx2]] = 1 } } } // write the final val of the diffMap to an array and return tempArray := make([]string, 0) for key, val := range tempMap { if val == 1 { tempArray = append(tempArray, key) } } return tempArray } // DistinctString removes duplicate values from one array. // // Deprecated: use Distinct instead. func DistinctString(arg []string) []string { tempMap := make(map[string]uint8) for idx := range arg { tempMap[arg[idx]] = 0 } tempArray := make([]string, 0) for key := range tempMap { tempArray = append(tempArray, key) } return tempArray } /* *************************************************************** * * THIS SECTION IS FOR uint64's * /* *************************************************************** */ // IntersectUint64 finds the intersection of two arrays. // // Deprecated: use Intersect instead. func IntersectUint64(args ...[]uint64) []uint64 { // create a map to count all the instances of the strings arrLength := len(args) tempMap := make(map[uint64]int) for _, arg := range args { tempArr := DistinctUint64(arg) for idx := range tempArr { // how many times have we encountered this elem? if _, ok := tempMap[tempArr[idx]]; ok { tempMap[tempArr[idx]]++ } else { tempMap[tempArr[idx]] = 1 } } } // find the keys equal to the length of the input args tempArray := make([]uint64, 0) for key, val := range tempMap { if val == arrLength { tempArray = append(tempArray, key) } } return tempArray } // DistinctIntersectUint64 finds the intersection of two arrays of distinct vals. // // Deprecated: use Intersect instead. func DistinctIntersectUint64(args ...[]uint64) []uint64 { // create a map to count all the instances of the strings arrLength := len(args) tempMap := make(map[uint64]int) for _, arg := range args { for idx := range arg { // how many times have we encountered this elem? if _, ok := tempMap[arg[idx]]; ok { tempMap[arg[idx]]++ } else { tempMap[arg[idx]] = 1 } } } // find the keys equal to the length of the input args tempArray := make([]uint64, 0) for key, val := range tempMap { if val == arrLength { tempArray = append(tempArray, key) } } return tempArray } func sortedIntersectUintHelper(a1 []uint64, a2 []uint64) []uint64 { intersection := make([]uint64, 0) n1 := len(a1) n2 := len(a2) i := 0 j := 0 for i < n1 && j < n2 { switch { case a1[i] > a2[j]: j++ case a2[j] > a1[i]: i++ default: intersection = append(intersection, a1[i]) i++ j++ } } return intersection } // SortedIntersectUint64 finds the intersection of two sorted arrays. // // Deprecated: use Intersect instead. func SortedIntersectUint64(args ...[]uint64) []uint64 { // create an array to hold the intersection and write the first array to it tempIntersection := args[0] argsLen := len(args) for k := 1; k < argsLen; k++ { // do we have any intersections? switch len(tempIntersection) { case 0: // nope! Give them an empty array! return tempIntersection default: // yup, keep chugging tempIntersection = sortedIntersectUintHelper(tempIntersection, args[k]) } } return tempIntersection } // IntersectUint64Arr finds the intersection of two arrays using a multidimensional array as inputs // // Deprecated: use Intersect instead. func IntersectUint64Arr(arr [][]uint64) []uint64 { // create a map to count all the instances of the strings arrLength := len(arr) tempMap := make(map[uint64]int) for idx1 := range arr { tempArr := DistinctUint64(arr[idx1]) for idx2 := range tempArr { // how many times have we encountered this elem? if _, ok := tempMap[tempArr[idx2]]; ok { tempMap[tempArr[idx2]]++ } else { tempMap[tempArr[idx2]] = 1 } } } // find the keys equal to the length of the input args tempArray := make([]uint64, 0) for key, val := range tempMap { if val == arrLength { tempArray = append(tempArray, key) } } return tempArray } // SortedIntersectUint64Arr finds the intersection of two arrays using a multidimensional array as inputs // // Deprecated: use Intersect instead. func SortedIntersectUint64Arr(arr [][]uint64) []uint64 { // create an array to hold the intersection and write the first array to it tempIntersection := arr[0] argsLen := len(arr) for k := 1; k < argsLen; k++ { // do we have any intersections? switch len(tempIntersection) { case 0: // nope! Give them an empty array! return tempIntersection default: // yup, keep chugging tempIntersection = sortedIntersectUintHelper(tempIntersection, arr[k]) } } return tempIntersection } // DistinctIntersectUint64Arr finds the intersection of two distinct arrays using a multidimensional array as inputs // // Deprecated: use Distinct instead. func DistinctIntersectUint64Arr(arr [][]uint64) []uint64 { // create a map to count all the instances of the strings arrLength := len(arr) tempMap := make(map[uint64]int) for idx1 := range arr { for idx2 := range arr[idx1] { // how many times have we encountered this elem? if _, ok := tempMap[arr[idx1][idx2]]; ok { tempMap[arr[idx1][idx2]]++ } else { tempMap[arr[idx1][idx2]] = 1 } } } // find the keys equal to the length of the input args tempArray := make([]uint64, 0) for key, val := range tempMap { if val == arrLength { tempArray = append(tempArray, key) } } return tempArray } // UnionUint64 finds the union of two arrays. // // Deprecated: use Union instead. func UnionUint64(args ...[]uint64) []uint64 { // create a temporary map to hold the contents of the arrays tempMap := make(map[uint64]uint8) // write the contents of the arrays as keys to the map. The map values don't matter for _, arg := range args { for idx := range arg { tempMap[arg[idx]] = 0 } } // the map keys are now unique instances of all of the array contents tempArray := make([]uint64, 0) for key := range tempMap { tempArray = append(tempArray, key) } return tempArray } // UnionUint64Arr finds the union of two arrays using a multidimensional array as inputs // // Deprecated: use Union instead. func UnionUint64Arr(arr [][]uint64) []uint64 { // create a temporary map to hold the contents of the arrays tempMap := make(map[uint64]uint8) // write the contents of the arrays as keys to the map. The map values don't matter for idx1 := range arr { for idx2 := range arr[idx1] { tempMap[arr[idx1][idx2]] = 0 } } // the map keys are now unique instances of all of the array contents tempArray := make([]uint64, 0) for key := range tempMap { tempArray = append(tempArray, key) } return tempArray } // DifferenceUint64 finds the difference of two arrays. // // Deprecated: use Difference instead. func DifferenceUint64(args ...[]uint64) []uint64 { // create a temporary map to hold the contents of the arrays tempMap := make(map[uint64]int) for _, arg := range args { tempArr := DistinctUint64(arg) for idx := range tempArr { // how many times have we encountered this elem? if _, ok := tempMap[tempArr[idx]]; ok { tempMap[tempArr[idx]]++ } else { tempMap[tempArr[idx]] = 1 } } } // write the final val of the diffMap to an array and return tempArray := make([]uint64, 0) for key, val := range tempMap { if val == 1 { tempArray = append(tempArray, key) } } return tempArray } // DifferenceUint64Arr finds the difference of two arrays using a multidimensional array as inputs. // // Deprecated: use Difference instead. func DifferenceUint64Arr(arr [][]uint64) []uint64 { // create a temporary map to hold the contents of the arrays tempMap := make(map[uint64]int) for idx1 := range arr { tempArr := DistinctUint64(arr[idx1]) for idx2 := range tempArr { // how many times have we encountered this elem? if _, ok := tempMap[tempArr[idx2]]; ok { tempMap[tempArr[idx2]]++ } else { tempMap[tempArr[idx2]] = 1 } } } // write the final val of the diffMap to an array and return tempArray := make([]uint64, 0) for key, val := range tempMap { if val == 1 { tempArray = append(tempArray, key) } } return tempArray } // DistinctUint64 removes duplicate values from one array. // // Deprecated: use Distinct instead. func DistinctUint64(arg []uint64) []uint64 { tempMap := make(map[uint64]uint8) for idx := range arg { tempMap[arg[idx]] = 0 } tempArray := make([]uint64, 0) for key := range tempMap { tempArray = append(tempArray, key) } return tempArray } arrayOperations-0.2.6/arrayOperations_unit_test.go000066400000000000000000000300601364564705300225240ustar00rootroot00000000000000package arrayOperations import ( "fmt" "reflect" "testing" ) var stringArr1 = []string{"a", "a", "b", "d"} var stringArr2 = []string{"b", "c", "e"} var intArr1 = []uint64{1, 1, 2, 4} var intArr2 = []uint64{2, 3, 5} var tempInterface interface{} func TestDistinct(t *testing.T) { var myTests = []struct { input interface{} pass bool expected interface{} }{ {stringArr1, true, []string{"a", "b", "d"}}, {stringArr2, true, []string{"b", "c", "e"}}, {intArr1, true, []uint64{1, 2, 4}}, {intArr2, true, []uint64{2, 3, 5}}, {[]int{}, true, []int{}}, } for _, tt := range myTests { actual, ok := Distinct(tt.input) if tt.pass && ok && !testEq(tt.expected, actual) { t.Errorf("expected: %v, received: %v", tt.expected, actual) } else if !tt.pass && ok { t.Errorf("expected fail but received: %v, ok: %v", actual, ok) } } } func TestIntersect(t *testing.T) { var myTests = []struct { input1 interface{} input2 interface{} pass bool expected interface{} }{ {stringArr1, stringArr2, true, []string{"b"}}, {intArr1, intArr2, true, []uint64{2}}, {stringArr1, intArr1, false, tempInterface}, {[]string{}, []string{"1"}, true, []string{}}, } for _, tt := range myTests { actual, ok := Intersect(tt.input1, tt.input2) if tt.pass && ok && !testEq(tt.expected, actual) { t.Errorf("expected: %v, received: %v", tt.expected, actual) } else if !tt.pass && ok { t.Errorf("expected fail but received: %v, ok: %v", actual, ok) } } } func TestUnion(t *testing.T) { var myTests = []struct { input1 interface{} input2 interface{} pass bool expected interface{} }{ {stringArr1, stringArr2, true, []string{"a", "b", "c", "d", "e"}}, {intArr1, intArr2, true, []uint64{1, 2, 3, 4, 5}}, {stringArr1, intArr1, false, tempInterface}, {[]string{}, []string{"1"}, true, []string{"1"}}, } for _, tt := range myTests { actual, ok := Union(tt.input1, tt.input2) if tt.pass && ok && !testEq(tt.expected, actual) { t.Errorf("expected: %v, received: %v", tt.expected, actual) } else if !tt.pass && ok { t.Errorf("expected fail but received: %v, ok: %v", actual, ok) } } } func TestDifference(t *testing.T) { var myTests = []struct { input1 interface{} input2 interface{} pass bool expected interface{} }{ {stringArr1, stringArr2, true, []string{"a", "c", "d", "e"}}, {intArr1, intArr2, true, []uint64{1, 3, 4, 5}}, {stringArr1, intArr1, false, tempInterface}, {[]string{}, []string{"1"}, true, []string{"1"}}, } for _, tt := range myTests { actual, ok := Difference(tt.input1, tt.input2) if tt.pass && ok && !testEq(tt.expected, actual) { t.Errorf("expected: %v, received: %v", tt.expected, actual) } else if !tt.pass && ok { t.Errorf("expected fail but received: %v, ok: %v", actual, ok) } } } func TestIntersectString(t *testing.T) { var myTests = []struct { input1 []string input2 []string expected []string }{ {stringArr1, stringArr2, []string{"b"}}, } for _, tt := range myTests { actual := IntersectString(tt.input1, tt.input2) if !testString(tt.expected, actual) { t.Errorf("expected: %v, received: %v", tt.expected, actual) } } } func TestIntersectStringArr(t *testing.T) { var myTests = []struct { input [][]string expected []string }{ {[][]string{stringArr1, stringArr2}, []string{"b"}}, } for _, tt := range myTests { actual := IntersectStringArr(tt.input) if !testString(tt.expected, actual) { t.Errorf("expected: %v, received: %v", tt.expected, actual) } } } func TestUnionString(t *testing.T) { var myTests = []struct { input1 []string input2 []string expected []string }{ {stringArr1, stringArr2, []string{"a", "b", "c", "d", "e"}}, } for _, tt := range myTests { actual := UnionString(tt.input1, tt.input2) if !testString(tt.expected, actual) { t.Errorf("expected: %v, received: %v", tt.expected, actual) } } } func TestUnionStringArr(t *testing.T) { var myTests = []struct { input [][]string expected []string }{ {[][]string{stringArr1, stringArr2}, []string{"a", "b", "c", "d", "e"}}, } for _, tt := range myTests { actual := UnionStringArr(tt.input) if !testString(tt.expected, actual) { t.Errorf("expected: %v, received: %v", tt.expected, actual) } } } func TestDifferenceString(t *testing.T) { var myTests = []struct { input1 []string input2 []string expected []string }{ {stringArr1, stringArr2, []string{"a", "c", "d", "e"}}, } for _, tt := range myTests { actual := DifferenceString(tt.input1, tt.input2) if !testString(tt.expected, actual) { t.Errorf("expected: %v, received: %v", tt.expected, actual) } } } func TestDifferenceStringArr(t *testing.T) { var myTests = []struct { input [][]string expected []string }{ {[][]string{stringArr1, stringArr2}, []string{"a", "c", "d", "e"}}, } for _, tt := range myTests { actual := DifferenceStringArr(tt.input) if !testString(tt.expected, actual) { t.Errorf("expected: %v, received: %v", tt.expected, actual) } } } func TestDistinctString(t *testing.T) { var myTests = []struct { input []string expected []string }{ {stringArr1, []string{"a", "b", "d"}}, {stringArr2, []string{"b", "c", "e"}}, } for _, tt := range myTests { actual := DistinctString(tt.input) if !testString(tt.expected, actual) { t.Errorf("expected: %v, received: %v", tt.expected, actual) } } } ///////////// ///////////// func TestIntersectUint64(t *testing.T) { var myTests = []struct { input1 []uint64 input2 []uint64 expected []uint64 }{ {intArr1, intArr2, []uint64{2}}, } for _, tt := range myTests { actual := IntersectUint64(tt.input1, tt.input2) if !testuInt64(tt.expected, actual) { t.Errorf("expected: %v, received: %v", tt.expected, actual) } } } func TestDistinctIntersectUint64(t *testing.T) { var myTests = []struct { input1 []uint64 input2 []uint64 expected []uint64 }{ {[]uint64{1, 2, 4}, []uint64{2, 3, 5}, []uint64{2}}, } for _, tt := range myTests { actual := DistinctIntersectUint64(tt.input1, tt.input2) if !testuInt64(tt.expected, actual) { t.Errorf("expected: %v, received: %v", tt.expected, actual) } } } func TestDistinctIntersectUint64Arr(t *testing.T) { var myTests = []struct { input [][]uint64 expected []uint64 }{ {[][]uint64{{1, 2, 4}, {2, 3, 5}}, []uint64{2}}, } for _, tt := range myTests { actual := DistinctIntersectUint64Arr(tt.input) if !testuInt64(tt.expected, actual) { t.Errorf("expected: %v, received: %v", tt.expected, actual) } } } func TestIntersectUint64Arr(t *testing.T) { var myTests = []struct { input [][]uint64 expected []uint64 }{ {[][]uint64{intArr1, intArr2}, []uint64{2}}, } for _, tt := range myTests { actual := IntersectUint64Arr(tt.input) if !testuInt64(tt.expected, actual) { t.Errorf("expected: %v, received: %v", tt.expected, actual) } } } func TestSortedIntersectUint64(t *testing.T) { var myTests = []struct { input1 []uint64 input2 []uint64 expected []uint64 }{ {[]uint64{1, 2, 4}, []uint64{2, 3, 5}, []uint64{2}}, } for _, tt := range myTests { actual := SortedIntersectUint64(tt.input1, tt.input2) if !testuInt64(tt.expected, actual) { t.Errorf("expected: %v, received: %v", tt.expected, actual) } } } func TestSortedIntersectUint64Arr(t *testing.T) { var myTests = []struct { input [][]uint64 expected []uint64 }{ {[][]uint64{{1, 2, 4}, {2, 3, 5}}, []uint64{2}}, } for _, tt := range myTests { actual := SortedIntersectUint64Arr(tt.input) if !testuInt64(tt.expected, actual) { t.Errorf("expected: %v, received: %v", tt.expected, actual) } } } func TestUnionUint64(t *testing.T) { var myTests = []struct { input1 []uint64 input2 []uint64 expected []uint64 }{ {intArr1, intArr2, []uint64{1, 2, 3, 4, 5}}, } for _, tt := range myTests { actual := UnionUint64(tt.input1, tt.input2) if !testuInt64(tt.expected, actual) { t.Errorf("expected: %v, received: %v", tt.expected, actual) } } } func TestUnionUint64Arr(t *testing.T) { var myTests = []struct { input [][]uint64 expected []uint64 }{ {[][]uint64{intArr1, intArr2}, []uint64{1, 2, 3, 4, 5}}, } for _, tt := range myTests { actual := UnionUint64Arr(tt.input) if !testuInt64(tt.expected, actual) { t.Errorf("expected: %v, received: %v", tt.expected, actual) } } } func TestDifferenceUint64(t *testing.T) { var myTests = []struct { input1 []uint64 input2 []uint64 expected []uint64 }{ {intArr1, intArr2, []uint64{1, 3, 4, 5}}, } for _, tt := range myTests { actual := DifferenceUint64(tt.input1, tt.input2) if !testuInt64(tt.expected, actual) { t.Errorf("expected: %v, received: %v", tt.expected, actual) } } } func TestDifferenceUint64Arr(t *testing.T) { var myTests = []struct { input [][]uint64 expected []uint64 }{ {[][]uint64{intArr1, intArr2}, []uint64{1, 3, 4, 5}}, } for _, tt := range myTests { actual := DifferenceUint64Arr(tt.input) if !testuInt64(tt.expected, actual) { t.Errorf("expected: %v, received: %v", tt.expected, actual) } } } func TestDistinctUint64(t *testing.T) { var myTests = []struct { input []uint64 expected []uint64 }{ {intArr1, []uint64{1, 2, 4}}, {intArr2, []uint64{2, 3, 5}}, } for _, tt := range myTests { actual := DistinctUint64(tt.input) if !testuInt64(tt.expected, actual) { t.Errorf("expected: %v, received: %v", tt.expected, actual) } } } // Examples func ExampleDistinct() { var a = []int{1, 1, 2, 3} z, ok := Distinct(a) if !ok { fmt.Println("Cannot find distinct") } slice, ok := z.Interface().([]int) if !ok { fmt.Println("Cannot convert to slice") } fmt.Println(slice, reflect.TypeOf(slice)) // [1, 2, 3] []int } func ExampleIntersect() { var a = []int{1, 1, 2, 3} var b = []int{2, 4} z, ok := Intersect(a, b) if !ok { fmt.Println("Cannot find intersect") } slice, ok := z.Interface().([]int) if !ok { fmt.Println("Cannot convert to slice") } fmt.Println(slice, reflect.TypeOf(slice)) // [2] []int } func ExampleUnion() { var a = []int{1, 1, 2, 3} var b = []int{2, 4} z, ok := Union(a, b) if !ok { fmt.Println("Cannot find union") } slice, ok := z.Interface().([]int) if !ok { fmt.Println("Cannot convert to slice") } fmt.Println(slice, reflect.TypeOf(slice)) // [1, 2, 3, 4] []int } func ExampleDifference() { var a = []int{1, 1, 2, 3} var b = []int{2, 4} z, ok := Difference(a, b) if !ok { fmt.Println("Cannot find difference") } slice, ok := z.Interface().([]int) if !ok { fmt.Println("Cannot convert to slice") } fmt.Println(slice, reflect.TypeOf(slice)) // [1, 3] []int } // Thanks! http://stackoverflow.com/a/15312097/3512709 func testEq(a, b interface{}) bool { if a == nil && b == nil { fmt.Println("Both nil") return true } if a == nil || b == nil { fmt.Println("One nil") return false } aSlice, ok := takeArg(a, reflect.Slice) if !ok { fmt.Println("Can't takeArg a") return ok } bSlice, ok := b.(reflect.Value) if !ok { fmt.Println("Can't takeArg b") return ok } aLen := aSlice.Len() bLen := bSlice.Len() if aLen != bLen { fmt.Println("Arr lengths not equal") return false } OUTER: for i := 0; i < aLen; i++ { foundVal := false for j := 0; j < bLen; j++ { if aSlice.Index(i).Interface() == bSlice.Index(j).Interface() { foundVal = true continue OUTER } } if !foundVal { return false } } return true } func testString(a, b []string) bool { if a == nil && b == nil { return true } if a == nil || b == nil { return false } if len(a) != len(b) { return false } OUTER: for _, aEl := range a { foundVal := false for _, bEl := range b { if aEl == bEl { foundVal = true continue OUTER } } if !foundVal { return false } } return true } func testuInt64(a, b []uint64) bool { if a == nil && b == nil { return true } if a == nil || b == nil { return false } if len(a) != len(b) { return false } OUTER: for _, aEl := range a { foundVal := false for _, bEl := range b { if aEl == bEl { foundVal = true continue OUTER } } if !foundVal { return false } } return true } arrayOperations-0.2.6/go.mod000066400000000000000000000000661364564705300160260ustar00rootroot00000000000000module github.com/adam-hanna/arrayOperations go 1.14