How to find an element intersect in other array - go

I have an array like:
a:= [1,2,3,4,5]
b:= [5,6,7,8,9]
How to know array b have contain element in array a without using foreach?

How to know array b have contain element in array a without using foreach?
You can't. And you should not try as this is pointless restriction.

If the arrays are sorted (as they appear to be in your question) there is an algorithm that works better than going through each element.
Pick the first element of a, call it x.
Binary search b for the first element equal or greater than x. If they are equal, you found an element that is contained in both arrays, if not, make that your new x. Now search a for x in the same way. Repeat until you run out of elements in one of the arrays.
This can be trivially extended to an arbitrary number of arrays (in fact, it's easier to write with an arbitrary number of arrays).
Here's a quick and dirty implementation:
package main
import (
"fmt"
"sort"
)
func inter(arrs ...[]int) []int {
res := []int{}
x := arrs[0][0]
i := 1
for {
off := sort.SearchInts(arrs[i], x)
if off == len(arrs[i]) {
// we emptied one slice, we're done.
break
}
if arrs[i][off] == x {
i++
if i == len(arrs) {
// x was in all the slices
res = append(res, x)
x++ // search for the next possible x.
i = 0
}
} else {
x = arrs[i][off]
i = 0 // This can be done a bit more optimally.
}
}
return res
}
func main() {
a := []int{1, 2, 3, 4, 5, 7}
b := []int{5, 6, 7, 8, 9}
fmt.Println(inter(a, b))
}

package main
import (
set "github.com/deckarep/golang-set"
)
func array_intersect(a, b []interface{}) []interface{} {
return set.NewSetFromSlice(a).Intersect(set.NewSetFromSlice(b)).ToSlice()
}
func main() {
a := []interface{}{1, 2, 3, 4, 5, 7}
b := []interface{}{5, 6, 7, 8, 9}
println(array_intersect(a, b))
}

package main
import (
"fmt"
"sort"
)
func array_intersect(a, b []int) []int {
ret := []int{}
lenA := len(a)
lenB := len(b)
if lenA == 0 || lenB == 0 {
return ret
}
sort.Ints(a)
sort.Ints(b)
var i, j int
for {
a = a[i:]
if i = sort.SearchInts(a, b[j]); i >= len(a) {
break
}
if a[i] == b[j] {
ret = append(ret, a[i])
}
if j++; j >= lenB {
break
}
}
return ret
}
func main() {
a := []int{5, 7, 1, 1, 2, 3, 4, 5, 7}
b := []int{1, 1, 5, 6, 7, 8, 9}
fmt.Printf("a=%v, b=%v", a, b)
fmt.Printf("%v\n", array_intersect(a, b))
fmt.Printf("a=%v, b=%v", a, b)
}

Related

Why do we use Slice int in golang

In the below program what can we call this - type Sequence [ ]int
I am unable to understand whether it's a sliced structure or anything else..
package main
import "fmt"
type Sequence []int
type Stats interface {
GreaterThan(x int) Sequence
}
func (s Sequence) GreaterThan(x int) (ans Sequence) {
for _, v := range s {
if v > x {
ans = append(ans, v)
}
}
return ans
}
func main() {
s := Sequence{5, 6, 4, 5, 2, 1, 1, 3, 2, 1, 7, 8}
fmt.Println("", s.GreaterThan(2))
}
Sequence is array of int
and s is slice from Sequence filled

Merge pointer to a slice

playground
package main
import (
"fmt"
"math/rand"
)
func randoms() *[]int {
var nums []int = make([]int, 5, 5) //Created slice with fixed Len, cap
fmt.Println(len(nums))
for i := range [5]int{} {//Added random numbers.
nums[i] = rand.Intn(10)
}
return &nums//Returning pointer to the slice
}
func main() {
fmt.Println("Hello, playground")
var nums []int = make([]int, 0, 25)
for _ = range [5]int{} {//Calling the functions 5 times
res := randoms()
fmt.Println(res)
//nums = append(nums, res)
for _, i := range *res {//Iterating and appending them
nums = append(nums, i)
}
}
fmt.Println(nums)
}
I am trying to mimic my problem. I have dynamic number of function calls i.e randoms and dynamic number of results. I need to append all of the results i.e numbers in this case.
I am able to do this with iteration and no issues with it. I am looking for a way to do something like nums = append(nums, res). Is there any way to do this/any built-in methods/did I misunderstand the pointers?
I think you're looking for append(nums, (*res)...):
nums = append(nums, (*res)...)
playground
See this answer for more about ..., but in short it expands the contents of a slice. Example:
x := []int{1, 2, 3}
y := []int{4, 5, 6}
x = append(x, y...) // Now x = []int{1, 2, 3, 4, 5, 6}
Further, since you have a pointer to a slice, you need to dereference the pointer with *.
x := []int{1, 2, 3}
y := &x
x = append(x, (*x)...) // x = []int{1, 2, 3, 1, 2, 3}

Change slice content and capacity inside a function in-place

I am trying to learn Go, so here is my very simple function for removing adjacent duplicates from slice for exercise from the book by Donovan & Kernighan.
Here is the code: https://play.golang.org/p/avHc1ixfck
package main
import "fmt"
func main() {
a := []int{0, 1, 1, 3, 3, 3}
removeDup(a)
fmt.Println(a)
}
func removeDup(s []int) {
n := len(s)
tmp := make([]int, 0, n)
tmp = append(tmp, s[0])
j := 1
for i := 1; i < n; i++ {
if s[i] != s[i-1] {
tmp = append(tmp, s[i])
j++
}
}
s = s[:len(tmp)]
copy(s, tmp)
}
It should print out [0 1 3] - and I checked, actually tmp at the end of the function it has desired form. However, the result is [0 1 3 3 3 3]. I guess there is something with copy function.
Can I somehow replace input slice s with the temp or trim it to desired length?
Option 1
Return a new slice as suggested by #zerkms.
https://play.golang.org/p/uGJiD3WApS
package main
import "fmt"
func main() {
a := []int{0, 1, 1, 3, 3, 3}
a = removeDup(a)
fmt.Println(a)
}
func removeDup(s []int) []int {
n := len(s)
tmp := make([]int, 0, n)
tmp = append(tmp, s[0])
for i := 1; i < n; i++ {
if s[i] != s[i-1] {
tmp = append(tmp, s[i])
}
}
return tmp
}
Option 2
Use pointers for pass-by-reference.
The same thing in effect as that of option1.
https://play.golang.org/p/80bE5Qkuuj
package main
import "fmt"
func main() {
a := []int{0, 1, 1, 3, 3, 3}
removeDup(&a)
fmt.Println(a)
}
func removeDup(sp *[]int) {
s := *sp
n := len(s)
tmp := make([]int, 0, n)
tmp = append(tmp, s[0])
for i := 1; i < n; i++ {
if s[i] != s[i-1] {
tmp = append(tmp, s[i])
}
}
*sp = tmp
}
Also, refer to following SO thread:
Does Go have no real way to shrink a slice? Is that an issue?
Here's two more slightly different ways to achieve what you want using sets and named types. The cool thing about named types is that you can create interfaces around them and can help with the readability of lots of code.
package main
import "fmt"
func main() {
// returning a list
a := []int{0, 1, 1, 3, 3, 3}
clean := removeDup(a)
fmt.Println(clean)
// creating and using a named type
nA := &newArrType{0, 1, 1, 3, 3, 3}
nA.removeDup2()
fmt.Println(nA)
// or... casting your orginal array to the named type
nB := newArrType(a)
nB.removeDup2()
fmt.Println(nB)
}
// using a set
// order is not kept, but a set is returned
func removeDup(s []int) (newArr []int) {
set := make(map[int]struct{})
for _, n := range s {
set[n] = struct{}{}
}
newArr = make([]int, 0, len(set))
for k := range set {
newArr = append(newArr, k)
}
return
}
// using named a typed
type newArrType []int
func (a *newArrType) removeDup2() {
x := *a
for i := range x {
f := i + 1
if f < len(x) {
if x[i] == x[f] {
x = x[:f+copy(x[f:], x[f+1:])]
}
}
}
// check the last 2 indexes
if x[len(x)-2] == x[len(x)-1] {
x = x[:len(x)-1+copy(x[len(x)-1:], x[len(x)-1+1:])]
}
*a = x
}

Golang remove elements when iterating over slice panics

I want delete some elements from a slice, and https://github.com/golang/go/wiki/SliceTricks advise this slice-manipulation:
a = append(a[:i], a[i+1:]...)
Then I coded below:
package main
import (
"fmt"
)
func main() {
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
for i, value := range slice {
if value%3 == 0 { // remove 3, 6, 9
slice = append(slice[:i], slice[i+1:]...)
}
}
fmt.Printf("%v\n", slice)
}
with go run hello.go, it panics:
panic: runtime error: slice bounds out of range
goroutine 1 [running]:
panic(0x4ef680, 0xc082002040)
D:/Go/src/runtime/panic.go:464 +0x3f4
main.main()
E:/Code/go/test/slice.go:11 +0x395
exit status 2
How can I change this code to get right?
I tried below:
1st, with a goto statement:
func main() {
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
Label:
for i, n := range slice {
if n%3 == 0 {
slice = append(slice[:i], slice[i+1:]...)
goto Label
}
}
fmt.Printf("%v\n", slice)
}
it works, but too much iteration
2nd, use another slice sharing same backing array:
func main() {
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
dest := slice[:0]
for _, n := range slice {
if n%3 != 0 { // filter
dest = append(dest, n)
}
}
slice = dest
fmt.Printf("%v\n", slice)
}
but not sure if this one is better or not.
3rd, from Remove elements in slice, with len operator:
func main() {
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
for i := 0; i < len(slice); i++ {
if slice[i]%3 == 0 {
slice = append(slice[:i], slice[i+1:]...)
i-- // should I decrease index here?
}
}
fmt.Printf("%v\n", slice)
}
which one should I take now?
with benchmark:
func BenchmarkRemoveSliceElementsBySlice(b *testing.B) {
for i := 0; i < b.N; i++ {
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
dest := slice[:0]
for _, n := range slice {
if n%3 != 0 {
dest = append(dest, n)
}
}
}
}
func BenchmarkRemoveSliceElementByLen(b *testing.B) {
for i := 0; i < b.N; i++ {
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
for i := 0; i < len(slice); i++ {
if slice[i]%3 == 0 {
slice = append(slice[:i], slice[i+1:]...)
}
}
}
}
$ go test -v -bench=".*"
testing: warning: no tests to run
PASS
BenchmarkRemoveSliceElementsBySlice-4 50000000 26.6 ns/op
BenchmarkRemoveSliceElementByLen-4 50000000 32.0 ns/op
it seems delete all elements in one loop is better
Iterate over the slice copying elements that you want to keep.
k := 0
for _, n := range slice {
if n%3 != 0 { // filter
slice[k] = n
k++
}
}
slice = slice[:k] // set slice len to remaining elements
The slice trick is useful in the case where a single element is deleted. If it's possible that more than one element will be deleted, then use the for loop above.
working playground example
while this is good answer for small slice:
package main
import "fmt"
func main() {
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
k := 0
for _, n := range slice {
if n%3 != 0 { // filter
slice[k] = n
k++
}
}
slice = slice[:k]
fmt.Println(slice) //[1 2 4 5 7 8]
}
for minimizing memory write for first elements (for big slice), you may use this:
package main
import "fmt"
func main() {
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
k := 0
for i, n := range slice {
if n%3 != 0 { // filter
if i != k {
slice[k] = n
}
k++
}
}
slice = slice[:k]
fmt.Println(slice) //[1 2 4 5 7 8]
}
and if you need new slice or preserving old slice:
package main
import "fmt"
func main() {
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
s2 := make([]int, len(slice))
k := 0
for _, n := range slice {
if n%3 != 0 { // filter
s2[k] = n
k++
}
}
s2 = s2[:k]
fmt.Println(s2) //[1 2 4 5 7 8]
}

How do I reverse an array in Go?

http://play.golang.org/p/W70J4GU7nA
s := []int{5, 2, 6, 3, 1, 4}
sort.Reverse(sort.IntSlice(s))
fmt.Println(s)
// 5, 2, 6, 3, 1, 4
It is hard to understand what it means in func Reverse(data Interface) Interface .
How do I reverse an array? I do not need to sort.
Honestly this one is simple enough that I'd just write it out like this:
package main
import "fmt"
func main() {
s := []int{5, 2, 6, 3, 1, 4}
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
s[i], s[j] = s[j], s[i]
}
fmt.Println(s)
}
http://play.golang.org/p/vkJg_D1yUb
(The other answers do a good job of explaining sort.Interface and how to use it; so I won't repeat that.)
Normally, to sort an array of integers you wrap them in an IntSlice, which defines the methods Len, Less, and Swap. These methods are in turn used by sort.Sort. What sort.Reverse does is that it takes an existing type that defines Len, Less, and Swap, but it replaces the Less method with a new one that is always the inverse of the underlying Less:
type reverse struct {
// This embedded Interface permits Reverse to use the methods of
// another Interface implementation.
Interface
}
// Less returns the opposite of the embedded implementation's Less method.
func (r reverse) Less(i, j int) bool {
return r.Interface.Less(j, i)
}
// Reverse returns the reverse order for data.
func Reverse(data Interface) Interface {
return &reverse{data}
}
So when you write sort.Reverse(sort.IntSlice(s)), whats happening is that you're getting this new, 'modified' IntSlice that has it's Less method replaced. So if you call sort.Sort on it, which calls Less, it will get sorted in decreasing order.
I'm 2 years late, but just for fun and interest I'd like to contribute an "oddball" solution.
Assuming the task really is to reverse a list, then for raw performance bgp's solution is probably unbeatable. It gets the job done simply and effectively by swapping array items front to back, an operation that's efficient in the random-access structure of arrays and slices.
In Functional Programming languages, the idiomatic approach would often involve recursion. This looks a bit strange in Go and will have atrocious performance. That said, here's a recursive array reversal function (in a little test program):
package main
import (
"fmt"
)
func main() {
myInts := []int{ 8, 6, 7, 5, 3, 0, 9 }
fmt.Printf("Ints %v reversed: %v\n", myInts, reverseInts(myInts))
}
func reverseInts(input []int) []int {
if len(input) == 0 {
return input
}
return append(reverseInts(input[1:]), input[0])
}
Output:
Ints [8 6 7 5 3 0 9] reversed: [9 0 3 5 7 6 8]
Again, this is for fun and not production. Not only is it slow, but it will overflow the stack if the list is too large. I just tested, and it will reverse a list of 1 million ints but crashes on 10 million.
First of all, if you want to reverse the array, do like this,
for i, j := 0, len(a)-1; i < j; i, j = i+1, j-1 {
a[i], a[j] = a[j], a[i]
}
Then, look at the usage of Reverse in golang.org
package main
import (
"fmt"
"sort"
)
func main() {
s := []int{5, 2, 6, 3, 1, 4} // unsorted
sort.Sort(sort.Reverse(sort.IntSlice(s)))
fmt.Println(s)
}
// output
// [6 5 4 3 2 1]
And look at the description of Reverse and Sort
func Reverse(data Interface) Interface
func Sort(data Interface)
Sort sorts data. It makes one call to data.Len to determine n, and O(n*log(n)) calls to data.Less and data.Swap. The sort is not guaranteed to be stable.
So, as you know, Sort is not just a sort algorithm, you can view it as a factory, when you use Reverse it just return a reversed sort algorithm, Sort is just doing the sorting.
This is a more generic slice reverse function. It will panic if input is not a slice.
//panic if s is not a slice
func ReverseSlice(s interface{}) {
size := reflect.ValueOf(s).Len()
swap := reflect.Swapper(s)
for i, j := 0, size-1; i < j; i, j = i+1, j-1 {
swap(i, j)
}
}
If you want to reverse the array, you can just go through it in reverse order. Since there is no "reverse range" primitive in the language (at least not yet), you must do something like this (http://play.golang.org/p/AhvAfMjs_7):
s := []int{5, 2, 6, 3, 1, 4}
for i := len(s) - 1; i >= 0; i-- {
fmt.Print(s[i])
if i > 0 {
fmt.Print(", ")
}
}
fmt.Println()
Regarding whether it is hard to understand what sort.Reverse(data Interface) Interface does, I thought the same until I saw the source code from "http://golang.org/src/pkg/sort/sort.go".
It just makes the comparisons required for the sorting to be made "the other way around".
Here is a simple Go solution that uses an efficient (no extra memory) approach to reverse an array:
i := 0
j := len(nums) - 1
for i < j {
nums[i], nums[j] = nums[j], nums[i]
i++
j--
}
The idea is that reversing an array is equivalent to swapping each element with its mirror image across the center.
https://play.golang.org/p/kLFpom4LH0g
Here is another way to do it
func main() {
example := []int{1, 25, 3, 5, 4}
sort.SliceStable(example, func(i, j int) bool {
return true
})
fmt.Println(example)
}
https://play.golang.org/p/-tIzPX2Ds9z
func Reverse(data Interface) Interface
This means that it takes a sort.Interface and returns another sort.Interface -- it doesn't actually doing any sorting itself. For example, if you pass in sort.IntSlice (which is essentially a []int that can be passed to sort.Sort to sort it in ascending order) you'll get a new sort.Interface which sorts the ints in descending order instead.
By the way, if you click on the function name in the documentation, it links directly to the source for Reverse. As you can see, it just wraps the sort.Interface that you pass in, so the value returned from Reverse gets all the methods of the original sort.Interface. The only method that's different is the Less method which returns the opposite of the Less method on the embedded sort.Interface. See this part of the language spec for details on embedded fields.
From Golang wiki SliceTricks:
To replace the contents of a slice with the same elements but in
reverse order:
for i := len(a)/2-1; i >= 0; i-- {
opp := len(a)-1-i
a[i], a[opp] = a[opp], a[i]
}
The same thing, except with two indices:
for left, right := 0, len(a)-1; left < right; left, right = left+1, right-1 {
a[left], a[right] = a[right], a[left]
}
To reverse an array in place, iterate to its mid-point, and swap each element with its "mirror element":
func main() {
xs := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
itemCount := len(xs)
for i := 0; i < itemCount/2; i++ {
mirrorIdx := itemCount - i -1
xs[i], xs[mirrorIdx] = xs[mirrorIdx], xs[i]
}
fmt.Printf("xs: %v\n", xs)
}
https://play.golang.org/p/JeSApt80_k
Here is a method using append:
package main
import "fmt"
func main() {
a := []int{10, 20, 30, 40, 50}
for n := len(a) - 2; n >= 0; n-- {
a = append(a[:n], append(a[n + 1:], a[n])...)
}
fmt.Println(a)
}
Drawing of the steps:
10 20 30 40 50
10 20 30 50 40
10 20 50 40 30
10 50 40 30 20
50 40 30 20 10
This answer is mainly for those beginners who wish to write this code using only one variable in the for loop instead of using two variables (like i & j).
package main
import "fmt"
func main() {
array := []int{45, 17, 43, 67, 21, 4, 97, 44, 54, 98, 665}
fmt.Println("initial array:", array)
loop_iteration := len(array)
if len(array)%2 == 0 {
loop_iteration = (len(array) / 2) - 1
} else {
loop_iteration = int(len(array) / 2) //This will give the lower integer value of that float number.
}
for i := 0; i <= loop_iteration; i++ {
array[i], array[(len(array)-1)-i] = array[(len(array)-1)-i], array[i]
}
fmt.Println("reverse array:", array)
}
https://go.dev/play/p/bVp0x7v6Kbs
package main
import (
"fmt"
)
func main() {
arr := []int{1, 2, 3, 4, 5}
fmt.Println(reverseArray(arr))
}
func reverseArray(arr []int) []int {
reversed := make([]int, len(arr))
j := 0
for i := len(arr) - 1; i >= 0; i-- {
reversed[j] = arr[i]
j++
}
return reversed
}
Simple solution without involving math. Like this solution, this is inefficient as it does too much allocation and garbage collection. Good for non-critical code where clarity is more important than performance. Playground: https://go.dev/play/p/dQGwrc0Q9ZA
arr := []int{1, 3, 4, 5, 6}
var rev []int
for _, n := range arr {
rev = append([]int{n}, rev...)
}
fmt.Println(arr)
fmt.Println(rev)
Its very simple if you want to print reverse array
Use Index from length doing i--
ex.
a := []int{5, 4, 12, 7, 15, 9}
for i := 0; i <= len(a)-1; i++ {
fmt.Println(a[len(a)-(i+1)])
}
https://go.dev/play/p/bmyFh7-_VCZ
Here is my solution.
package main
import (
"fmt"
)
func main() {
var numbers = [10]int {1,2,3,4,5,6,7,8,9,10}
var reverseNumbers [10]int
j:=0
for i:=len(numbers)-1; i>=0 ; i-- {
reverseNumbers[j]=numbers[i]
j++
}
fmt.Println(reverseNumbers)
}
Here is my solution to reversing an array:
func reverse_array(array []string) []string {
lenx := len(array) // lenx holds the original array length
reversed_array := make([]string, lenx) // creates a slice that refer to a new array of length lenx
for i := 0; i < lenx; i++ {
j := lenx - (i + 1) // j initially holds (lenx - 1) and decreases to 0 while i initially holds 0 and increase to (lenx - 1)
reversed_array[i] = array[j]
}
return reversed_array
}
You can try this solution on the go playground the go playground
package main
import "fmt"
func main() {
array := []string{"a", "b", "c", "d"}
fmt.Println(reverse_array(array)) // prints [d c b a]
}
Do not reverse it, leave it as now and then just iterate it backwards.

Resources