Can I iterate through a string using for c := range<string> but only use the character and not the index? - go

Basically I want to iterate through a string getting each character and doing something with that character. However when I try to loop through the string I have to provide one variable for the index of the character and one for the character itself ie. for pos, char := range myString {*do something*}. How do I do simply assign the character itself without having to assign the index?

The range form of the for loop iterates over a slice or map.
When ranging over a slice, two values are returned for each iteration:
The first is the index of the slice;
The second is a copy of the element at that index.
Let's assume that we have a function that verify if a number is a prime number, and we have an array with the candidate numbers, than we can call the function in two different way:
var prime []int = []int{2, 3, 5, 7, 11, 13, 17, 19, 23}
func TestIsPrimeByValue(t *testing.T) {
for _, item := range prime {
if !IsPrime(item) {
t.Fail()
}
}
}
func TestIsPrimeByIndex(t *testing.T) {
for i := range prime {
if !IsPrime(prime[i]) {
t.Fail()
}
}
}
With the first loop, we are iterating the value of the array.
With the second loop, we are iterating the index of the array. This is an example with int. You can replace the array with a string and iterate the bytes of the string.

Related

Get all combinations of a slice until a certain length

I am using the go combinations package to find all the combinations of a list of ints. The package out of the box is for strings but I've edited to do []int instead.
func All(set []int) (subsets [][]int) {
length := uint(len(set))
// Go through all possible combinations of objects
// from 1 (only first object in subset) to 2^length (all objects in subset)
for subsetBits := 1; subsetBits < (1 << length); subsetBits++ {
var subset []int
for object := uint(0); object < length; object++ {
// checks if object is contained in subset
// by checking if bit 'object' is set in subsetBits
if (subsetBits>>object)&1 == 1 {
// add object to subset
subset = append(subset, set[object])
}
}
// add subset to subsets
subsets = append(subsets, subset)
}
return subsets
}
This works for me, however, only when given a small slice. once the slice gets large the combinations become exponential and tolling to calculate.
Luckily I know when I need to stop. Before running the combinations I have determined the max length of the combinations.
s := []int{2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4}
limit := 2
The above would generate an exorbent amount of combinations, majority I will not need, as I can define the limit to the length of combinations I'd need as a maximum.
// Ideal output
[[2] [2] [2] [2] ...... [2 3] [2 4]] // Stop once we hit length of 3 as limit was set to 2
I can't really figure out how to implement a limit break or return once the combinations reach a certain length.
Example:
func All(set []int, limit int) (subsets [][]int) {
// ... previous code here
if len(combinations) > limit {
return output
}
}

Print permutations of a string given an index

I'm trying to learn recursion and going through the Stanford online video lectures and textbook. In the programming exercises a question is posed to generate all permutations for a string given an index. For example "ABCD" and index 2. This should generate "ABCD" and "ABDC".
I understand how to generate the permutations by using func permute(prefix, suffix) but this question is confusing me. Here is want I have so far:
func permute(s string) {
permuteHelper(s, 2)
}
func permuteHelper(s string, idx int) {
if idx == 0 {
fmt.Println(s)
return
}
for i := idx; i < len(s); i++ {
newS := s[:idx]
suffix := s[idx : idx+1]
newS += suffix
permuteHelper(newS, idx-1)
}
}
Output:
AB
AB
AB
AB
I don't want the answer, but perhaps some guidance in my thought process. I know I should create a static "AB" and then select "C" on one iteration and then select "D", then my base case should be triggered and print the string. Control will then return to "AB" and "i" should be 3 and I choose "D", but how do I then chose "C"?
You're on the right track and the overall form looks fine, but the details are still blurry.
Firstly,
newS := s[:idx]
suffix := s[idx : idx+1]
newS += suffix
is equivalent to
newS := s[:idx+1]
No real permuting is going on here; this is chopping off the back of the string and ignoring the loop variable i entirely. Try to swap two characters in the string for each recursive call and use both i and idx to do so; think of idx as a fixed pivot for swapping every i...len(s) element with per call frame. Good job ensuring you're not reassigning to the string in the current scope, though, because that'd mess up state for later iterations of the loop.
Second suggestion: To establish the base case, count recursively up to len(s) instead of down to zero. You can pretty much pretend the entire first chunk of the array doesn't exist. Think of it just like a regular permutation algorithm except you've skipped the first idx indices.
Also, this is more of a design point than an algorithmic issue, but I would expose the idx parameter to the caller instead of hiding it behind a wrapper. This makes the function reusable and more obvious as to what it does--as a user of a library, I'd be perplexed if a function named permute refused to permute the first 2 chars.
It's better to return a result than produce a side effect like printing, but I'll set that aside for pedagogy's sake.
Here's one solution (spoiler alert!):
package main
import "fmt"
func permute(s string, idx int) {
if idx == len(s) {
fmt.Println(s)
}
for i := idx; i < len(s); i++ {
a := []rune(s)
a[i], a[idx] = a[idx], a[i]
permute(string(a), idx + 1)
}
}
func main() {
permute("abcde", 2)
}
permute("abcde", 2) produces
abcde
abced
abdce
abdec
abedc
abecd

cap vs len of slice in golang

What is the difference between cap and len of a slice in golang?
According to definition:
A slice has both a length and a capacity.
The length of a slice is the number of elements it contains.
The capacity of a slice is the number of elements in the underlying array, counting from the first element in the slice.
x := make([]int, 0, 5) // len(b)=0, cap(b)=5
Does the len mean non null values only?
A slice is an abstraction that uses an array under the covers.
cap tells you the capacity of the underlying array. len tells you how many items are in the array.
The slice abstraction in Go is very nice since it will resize the underlying array for you, plus in Go arrays cannot be resized so slices are almost always used instead.
Example:
s := make([]int, 0, 3)
for i := 0; i < 5; i++ {
s = append(s, i)
fmt.Printf("cap %v, len %v, %p\n", cap(s), len(s), s)
}
Will output something like this:
cap 3, len 1, 0x1040e130
cap 3, len 2, 0x1040e130
cap 3, len 3, 0x1040e130
cap 6, len 4, 0x10432220
cap 6, len 5, 0x10432220
As you can see once the capacity is met, append will return a new slice with a larger capacity. On the 4th iteration you will notice a larger capacity and a new pointer address.
Play example
I realize you did not ask about arrays and append but they are pretty foundational in understanding the slice and the reason for the builtins.
From the source code:
// The len built-in function returns the length of v, according to its type:
// Array: the number of elements in v.
// Pointer to array: the number of elements in *v (even if v is nil).
// Slice, or map: the number of elements in v; if v is nil, len(v) is zero.
// String: the number of bytes in v.
// Channel: the number of elements queued (unread) in the channel buffer;
// if v is nil, len(v) is zero.
func len(v Type) int
// The cap built-in function returns the capacity of v, according to its type:
// Array: the number of elements in v (same as len(v)).
// Pointer to array: the number of elements in *v (same as len(v)).
// Slice: the maximum length the slice can reach when resliced;
// if v is nil, cap(v) is zero.
// Channel: the channel buffer capacity, in units of elements;
// if v is nil, cap(v) is zero.
func cap(v Type) int
Simple explanation
Slice are self growing form of array so there are two main properties.
Length is total no of elements() the slice is having and can be used for looping through the elements we stored in slice. Also when we print the slice all elements till length gets printed.
Capacity is total no elements in underlying array, when you append more elements the length increases till capacity. After that any further append to slice causes the capacity to increase automatically(apprx double) and length by no of elements appended.
The real magic happens when you slice out sub slices from a slice where all the actual read/write happens on the underlaying array. So any change in sub slice will also change data both in original slice and underlying array. Where as any sub slices can have their own length and capacity.
Go through the below program carefully. Its modified version of golang tour example
package main
import "fmt"
func main() {
sorig := []int{2, 3, 5, 7, 11, 13}
printSlice(sorig)
// Slice the slice to give it zero length.
s := sorig[:0]
printSlice(s)
// Extend its length.
s = s[:4]
s[2] = 555
printSlice(s)
// Drop its first two values.
s = s[2:]
printSlice(s)
printSlice(sorig)
}
func printSlice(s []int) {
fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
//Output
//len=6 cap=6 [2 3 5 7 11 13]
//len=0 cap=6 []
//len=4 cap=6 [2 3 555 7]
//len=2 cap=4 [555 7]
//len=6 cap=6 [2 3 555 7 11 13]

Create array of array literal in Golang

How do I create an array of int arrays in Golang using slice literals?
I've tried
test := [][]int{[1,2,3],[1,2,3]}
and
type Test struct {
foo [][]int
}
bar := Test{foo: [[1,2,3], [1,2,3]]}
You almost have the right thing however your syntax for the inner arrays is slightly off, needing curly braces like; test := [][]int{[]int{1,2,3},[]int{1,2,3}} or a slightly more concise version; test := [][]int{{1,2,3},{1,2,3}}
The expression is called a 'composite literal' and you can read more about them here; https://golang.org/ref/spec#Composite_literals
But as a basic rule of thumb, if you have nested structures, you have to use the syntax recursively. It's very verbose.
In some other langauges (Perl, Python, JavaScript), [1,2,3] might be an array literal, but in Go, composite literals use braces, and here, you have to specify the type of the outer slice:
package main
import "fmt"
type T struct{ foo [][]int }
func main() {
a := [][]int{{1, 2, 3}, {4, 5, 6}}
b := T{foo: [][]int{{1, 2, 3}, {4, 5, 6}}}
fmt.Println(a, b)
}
You can run or play with that on the Playground.
The Go compiler is just tricky enough to figure out that the elements of an [][]int are []int without you saying so on each element. You do have to write out the outer type's name, though.
Just replace the square brackets with curly braces. In Go, array literals are identified with curly braces.
test := [][]int{{1,2,3},{1,2,3}}
A slice literal is written as []type{<value 1>, <value 2>, ... }. A slice of ints would be []int{1,2,3} and a slice of int slices would be [][]int{[]int{1,2,3},[]int{4,5,6}}.
groups := [][]int{[]int{1,2,3},[]int{4,5,6}}
for _, group := range groups {
sum := 0
for _, num := range group {
sum += num
}
fmt.Printf("The array %+v has a sum of %d\n", sub, sum)
}

Checking the equality of two slices

How can I check if two slices are equal, given that the operators == and != are not an option?
package main
import "fmt"
func main() {
s1 := []int{1, 2}
s2 := []int{1, 2}
fmt.Println(s1 == s2)
}
This does not compile with:
invalid operation: s1 == s2 (slice can only be compared to nil)
You should use reflect.DeepEqual()
DeepEqual is a recursive relaxation of Go's == operator.
DeepEqual reports whether x and y are “deeply equal,” defined as
follows. Two values of identical type are deeply equal if one of the
following cases applies. Values of distinct types are never deeply
equal.
Array values are deeply equal when their corresponding elements are
deeply equal.
Struct values are deeply equal if their corresponding fields, both
exported and unexported, are deeply equal.
Func values are deeply equal if both are nil; otherwise they are not
deeply equal.
Interface values are deeply equal if they hold deeply equal concrete
values.
Map values are deeply equal if they are the same map object or if they
have the same length and their corresponding keys (matched using Go
equality) map to deeply equal values.
Pointer values are deeply equal if they are equal using Go's ==
operator or if they point to deeply equal values.
Slice values are deeply equal when all of the following are true: they
are both nil or both non-nil, they have the same length, and either
they point to the same initial entry of the same underlying array
(that is, &x[0] == &y[0]) or their corresponding elements (up to
length) are deeply equal. Note that a non-nil empty slice and a nil
slice (for example, []byte{} and []byte(nil)) are not deeply equal.
Other values - numbers, bools, strings, and channels - are deeply
equal if they are equal using Go's == operator.
You need to loop over each of the elements in the slice and test. Equality for slices is not defined. However, there is a bytes.Equal function if you are comparing values of type []byte.
func testEq(a, b []Type) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if a[i] != b[i] {
return false
}
}
return true
}
This is just example using reflect.DeepEqual() that is given in #VictorDeryagin's answer.
package main
import (
"fmt"
"reflect"
)
func main() {
a := []int {4,5,6}
b := []int {4,5,6}
c := []int {4,5,6,7}
fmt.Println(reflect.DeepEqual(a, b))
fmt.Println(reflect.DeepEqual(a, c))
}
Result:
true
false
Try it in Go Playground
If you have two []byte, compare them using bytes.Equal. The Golang documentation says:
Equal returns a boolean reporting whether a and b are the same length and contain the same bytes. A nil argument is equivalent to an empty slice.
Usage:
package main
import (
"fmt"
"bytes"
)
func main() {
a := []byte {1,2,3}
b := []byte {1,2,3}
c := []byte {1,2,2}
fmt.Println(bytes.Equal(a, b))
fmt.Println(bytes.Equal(a, c))
}
This will print
true
false
And for now, here is https://github.com/google/go-cmp which
is intended to be a more powerful and safer alternative to reflect.DeepEqual for comparing whether two values are semantically equal.
package main
import (
"fmt"
"github.com/google/go-cmp/cmp"
)
func main() {
a := []byte{1, 2, 3}
b := []byte{1, 2, 3}
fmt.Println(cmp.Equal(a, b)) // true
}
You cannot use == or != with slices but if you can use them with the elements then Go 1.18 has a new function to easily compare two slices, slices.Equal:
Equal reports whether two slices are equal: the same length and all elements equal. If the lengths are different, Equal returns false. Otherwise, the elements are compared in increasing index order, and the comparison stops at the first unequal pair. Floating point NaNs are not considered equal.
The slices package import path is golang.org/x/exp/slices. Code inside exp package is experimental, not yet stable. It will be moved into the standard library in Go 1.19 eventually.
Nevertheless you can use it as soon as Go 1.18 (playground)
sliceA := []int{1, 2}
sliceB := []int{1, 2}
equal := slices.Equal(sliceA, sliceB)
fmt.Println(equal) // true
type data struct {
num float64
label string
}
sliceC := []data{{10.99, "toy"}, {500.49, "phone"}}
sliceD := []data{{10.99, "toy"}, {200.0, "phone"}}
equal = slices.Equal(sliceC, sliceD)
fmt.Println(equal) // true
If the elements of the slice don't allow == and !=, you can use slices.EqualFunc and define whatever comparator function makes sense for the element type.
In case that you are interested in writing a test, then github.com/stretchr/testify/assert is your friend.
Import the library at the very beginning of the file:
import (
"github.com/stretchr/testify/assert"
)
Then inside the test you do:
func TestEquality_SomeSlice (t * testing.T) {
a := []int{1, 2}
b := []int{2, 1}
assert.Equal(t, a, b)
}
The error prompted will be:
Diff:
--- Expected
+++ Actual
## -1,4 +1,4 ##
([]int) (len=2) {
+ (int) 1,
(int) 2,
- (int) 2,
(int) 1,
Test: TestEquality_SomeSlice
Thought of a neat trick and figured I'd share.
If what you are interested in knowing is whether two slices are identical (i.e. they alias the same region of data) instead of merely equal (the value at each index of one slice equals the value in the same index of the other) then you can efficiently compare them in the following way:
foo := []int{1,3,5,7,9,11,13,15,17,19}
// these two slices are exactly identical
subslice1 := foo[3:][:4]
subslice2 := foo[:7][3:]
slicesEqual := &subslice1[0] == &subslice2[0] &&
len(subslice1) == len(subslice2)
There are some caveats to this sort of comparison, in particular that you cannot compare empty slices in this way, and that the capacity of the slices isn't compared, so this "identicality" property is only really useful when reading from a slice or reslicing a strictly narrower subslice, as any attempt to grow the slice will be affected by the slices' capacity. Still, it's very useful to be able to efficiently declare, "these two huge blocks of memory are in fact the same block, yes or no."
To have a complete set of answers: here is a solution with generics.
func IsEqual[A comparable](a, b []A) bool {
// Can't be equal if length differs
if len(a) != len(b) {
return false
}
// Empty arrays trivially equal
if len(a) == 0 {
return true
}
// Two pointers going towards each other at every iteration
left := 0
right := len(a) - 1
for left < right {
if a[left] != b[left] || a[right] != b[right] {
return false
}
left++
right--
}
return true
}
Code uses strategy of "two pointers" which brings runtime complexity of n / 2, which is still O(n), however, twice as less steps than a linear check one-by-one.

Resources