Why is my array not growing? - arrays

I am trying to generate numbers that are factors of 3 || 5 in an array.
Here is a copy of my code:
package main
import "fmt"
func main() {
i := 0
for i < 1000 {
var nums []int
if i%3 == 0 || i%5 == 0 {
nums := append(nums, i)
fmt.Println(nums)
}
i++
}
}
Unfortunately, this isnt going as planned as it appears to by over writing the value at nums[0]. Here a the last few values of my terminal output.
[981]
[984]
[985]
[987]
[990]
[993]
[995]
[996]
[999]
What am I doing wrong?
UPDATE
Also tried this:
var nums []int // initialize the slice outside for loop
for i < 1000 {
if i%3 == 0 || i%5 == 0 {
nums = append(nums, i) // append to the slice outside loop not create a new one using short variable declaration
fmt.Println(nums)
}
i++
}
But got Same result

This is because you are creating a new variable of []int slice rather than appending to the created one outside if condition. Create the []int slice outside for loop and don't create a new variable using short declaration inside if condition.
package main
import (
"fmt"
)
func main() {
i := 0
var nums []int
for i < 1000 {
if i%3 == 0 || i%5 == 0 {
nums = append(nums, i)
}
i++
}
fmt.Println(nums)
fmt.Println(len(nums), cap(nums)) // check for length and capacity of slice to know the size of slice after appending all data
}
Working Code on Go playground

Related

How to store struct with map into an Array in the go language

I made a package that looks like this...
package foo
type Foo struct {
num int
aMap map[int](int)
}
func MakeFoo() BookState {
return Foo{
num: -1,
aMap: make(map[int](int)),
}
}
I'm processing rows of a file like this
nrows :=100
arrayFoo = make([]Foo, nrows)
Foo = foo.MakeFoo()
count := 0
for int i=0; i < nrows; i++ {
row = myWrappedReader.ReadLine()
foo.num = i
foo.aMap[key] += row.otherNum
arrayFoo[i] = foo
}
But then when I go to check the arrayFoo at the end I have something that looks like this
[{num:1, aMap:{/*final state*/}, {num:2, aMap:{/*final state*/}, ...]
So the integer is updating but I need a copy of aMap to be stored instead of just the pointer to aMap.
Update:
Here's a playground.
Update2:
Here's a version that works. My class is quite a bit more complicated than this so I think I'll write a helper function in package foo that clone it.
Is there a easier way to copy maps or do most people do that?
Anything requiring a deep copy, as mentioned in "Is there a built in function in go for making copies of arbitrary maps?", would involve a dedicated function.
Example in this gist:
package deepcopy
import (
"bytes"
"encoding/gob"
)
func init() {
gob.Register(map[string]interface{}{})
}
// Map performs a deep copy of the given map m.
func Map(m map[string]interface{}) (map[string]interface{}, error) {
var buf bytes.Buffer
enc := gob.NewEncoder(&buf)
dec := gob.NewDecoder(&buf)
err := enc.Encode(m)
if err != nil {
return nil, err
}
var copy map[string]interface{}
err = dec.Decode(&copy)
if err != nil {
return nil, err
}
return copy, nil
}
Based on the suggestion of mkopriva replacing the line foo.aMap[key] += i with foo.aMap = map[string]int{"key": foo.aMap[key] + i}
package main
import (
"fmt"
)
type Foo struct {
num int
aMap map[string](int)
}
func MakeFoo() Foo {
return Foo{
num: -1,
aMap: make(map[string](int)),
}
}
func main() {
foo := MakeFoo()
key := "tmp"
foo.aMap[key] = 0
fmt.Println(foo)
arrayFoo := make([]Foo, 10)
for i := 0; i < 10; i++ {
foo.num = i
foo.aMap = map[string]int{"key": foo.aMap[key] + i}
arrayFoo[i] = foo
}
fmt.Println(arrayFoo)
}
Output:
{-1 map[tmp:0]}
[{0 map[key:0]} {1 map[key:1]} {2 map[key:2]} {3 map[key:3]} {4 map[key:4]} {5 map[key:5]} {6 map[key:6]} {7 map[key:7]} {8 map[key:8]} {9 map[key:9]}]

Second array will not increment after repeating for loop

I am new to Kotlin and am trying to compare the elements of two arrays by seeing which array has the greater element. The arrays are created via user input. The error that I am having is that when I repeat the second for loop (inner loop), which contains the contents of the second array, it will not increment to the next element of the second array unlike the first for loop. So if a = {1,2} and b = {2,1}, a would increment through both 1 and 2, but b would stay at 2 through both iterations of the loop. Here is my function that is giving me a problem:
fun practiceCompareArray(a: Array<Int>, b: Array<Int>): Array<Int> {
var j: Array<Int>
var aPoints = 0
var bPoints = 0
for (x:Int in a) {
---------> for (y: Int in b) {
if (x > y) {
aPoints++
} else if (x < y) {
bPoints++
break
}
}
j = arrayOf(aPoints, bPoints)
return j
}
The for loop with the arrow is giving me the problem. I think it is because of the break statement at the end of the inner loop. Do I even need the inner loop to compare each array? Any help or documentation would be helpful.
If you know that both array have the same length and you want to compare them elementwise you could do something like:
fun practiceCompareArray(a: Array<Int>, b: Array<Int>): Array<Int> {
var aPoints = 0
var bPoints = 0
for ((x,y) in a.zip(b)) {
if (x>y) {
aPoints ++
} else {
bPoints ++
}
}
return arrayOf(aPoints, bPoints)
}
or in a more functional style
fun practiceCompareArray(a: Array<Int>, b: Array<Int>): Array<Int> {
val (aPoints, bPoints) = a.zip(b)
.fold(Pair(0,0), {(aScore, bScore), (x,y) ->
if (x > y) Pair(aScore + 1, bScore) else Pair(aScore, bScore + 1)})
return arrayOf(aPoints, bPoints)
}

How do I find the longest strings in the array?

Actually I am able to get it done using two loops in Go Language, for example if I have array as:
["aa", "aab", "bcd", "a", "cdf", "bb"]
I need to return strings with maxLength. So output will be:
["aab", "bcd", "cdf"]
Here's what I am doing.
package main
import "fmt"
func allLongestStrings(inputArray []string) []string {
maxLength := len(inputArray[0])
outputArray := []string{}
for _, value := range inputArray {
if len(value) > maxLength {
maxLength = len(value)
}
}
for _, val := range inputArray {
if len(val) == maxLength {
outputArray = append(outputArray, val)
}
}
return outputArray
}
func main() {
xs := []string{"aa", "aab", "bcd", "a", "cdf", "bb"}
fmt.Println(allLongestStrings(xs))
}
Is it possible to do this in one loop because I am running the same loop twice to find length and to append strings in outputArray.
Thanks In Advance.
Try this:
func allLongestStrings(inputArray []string) []string {
max := -1 // -1 is guaranteed to be less than length of string
var result []string
for _, s := range inputArray {
if len(s) < max {
// Skip shorter string
continue
}
if len(s) > max {
// Found longer string. Update max and reset result.
max = len(s)
result = result[:0]
}
// Add to result
result = append(result, s)
}
return result
}
As peterSO points out in another answer, the result slice can have a capacity larger than required and can contain string values past the length of slice. The extra allocation and string references may be a problem in some contexts (result is retained for a long time, strings are large, ...). Return a copy of the slice if the allocation and references are a concern.
func allLongestStrings(inputArray []string) []string {
...
return append([]string(nil), result...)
}
If the function can mutate the original slice, then the function result can be constructed in the input slice. This avoids the allocation of the result slice.
func allLongestStrings(inputArray []string) []string {
n := 0
max := -1
for i, s := range inputArray {
if len(s) < max {
// Skip shorter string
continue
}
if len(s) > max {
// Found longer string. Update max and reset result.
max = len(s)
n = 0
}
inputArray[n], inputArray[i] = inputArray[i], inputArray[n]
n++
}
return inputArray[:n]
}
I would do it by using the sort package. Basically, what you do is to create a custom sort function by implementing sort.Interface and use sort.Sort to your advantage.
package main
import "sort"
import "fmt"
type sortByLength []string
// Len implements Len of sort.Interface
func (s sortByLength) Len() int {
return len(s)
}
// Swap implements Swap of sort.Interface
func (s sortByLength) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
// Less implements Less of sort.Interface
func (s sortByLength) Less(i, j int) bool {
return len(s[i]) > len(s[j])
}
func main() {
toFind := []string{"aa", "aab", "bcd", "a", "cdf", "bb"}
// We sort it by length, descending
sort.Sort(sortByLength(toFind))
// The first element is sure to be the longest
longest := []string{toFind[0]}
// In case we have more than one element in toFind...
if len(toFind) > 1 {
// ...we need to find all remaining elements of toFind...
for _, str := range toFind[1:] {
// ...which are not smaller than the first element of longest.
if len(str) < len(longest[0]) {
// In case the current element is smaller in length, we can stop iterating
// over toFind.
break
}
// We know that str has the same length as longest[0], so we append it
longest = append(longest, str)
}
}
fmt.Println(longest)
}
Run it on Playground
However, while only having one loop in your own code, the sorting obviously iterates over the input, too.
For example, a more efficient version of #ThunderCat's solution,
package main
import "fmt"
func longest(a []string) []string {
var l []string
if len(a) > 0 {
l = append(l, a[0])
a = a[1:]
}
for _, s := range a {
if len(l[0]) <= len(s) {
if len(l[0]) < len(s) {
l = l[:0]
}
l = append(l, s)
}
}
return append([]string(nil), l...)
}
func main() {
a := []string{"aa", "aab", "bcd", "a", "cdf", "bb"}
fmt.Println(len(a), a)
l := longest(a)
fmt.Println(len(l), cap(l), l)
}
Playground: https://play.golang.org/p/JTvl4wVvSEK
Output:
6 [aa aab bcd a cdf bb]
3 4 [aab bcd cdf]
Reading #ThunderCat's solution, there is room for improvement. For example, for maximum and minimum problems, avoid using special values as an initial maximum or minimimun value. Don't overallocate memory and don't leave dangling pointers.
A Go string is implemented as:
type stringStruct struct {
str unsafe.Pointer
len int
}
If the list consists of 1,000 strings of length 1,000 followed by one string of length 1,001, the returned list will have a length of one and a capacity of at least 1,000. 999 entries have dangling pointers to 1,000 byte strings which the Go gc will be unable to release, wasting over one megabyte.
package main
import (
"fmt"
"strings"
"unsafe"
)
type stringStruct struct {
str unsafe.Pointer
len int
}
func main() {
var l []string
for n := 0; n < 1000; n++ {
l = append(l, strings.Repeat("x", 1000))
}
l = l[:0]
l = append(l, strings.Repeat("y", 1001))
over := (cap(l) - len(l)) * int(unsafe.Sizeof(stringStruct{}))
for i, o := len(l), l[:cap(l)]; i < cap(l); i++ {
over += len(o[i])
}
fmt.Println(over) // 1015368 bytes 64-bit, 1007184 bytes 32-bit
}
Playground: https://play.golang.org/p/Fi7EgbvdVkp
For a program to be correct, it must be readable. First, write the fundamental algorithms without the distraction of errors or special cases.
var l []string
for _, s := range a {
if len(l[0]) <= len(s) {
if len(l[0]) < len(s) {
l = l[:0]
}
l = append(l, s)
}
}
Next, add special cases, without disrupting the flow of the fundamental algorithm. In this case, handle zero- and one-length lists.
var l []string
if len(a) > 0 {
l = append(l, a[0])
a = a[1:]
}
for _, s := range a {
if len(l[0]) <= len(s) {
if len(l[0]) < len(s) {
l = l[:0]
}
l = append(l, s)
}
}
Finally, ensure that the function is efficient for both CPU and memory. The allocation is precise and there are no dangling pointers to unused strings.
var l []string
if len(a) > 0 {
l = append(l, a[0])
a = a[1:]
}
for _, s := range a {
if len(l[0]) <= len(s) {
if len(l[0]) < len(s) {
l = l[:0]
}
l = append(l, s)
}
}
return append([]string(nil), l...)

Inserting integer into array in swift

I'm not really on point with Swift yet and there is a problem that is starting to be a tad annoying.
I just want to add integer in a double dimensional array but it is always returning the same error code : "fatal error : Array index out of range"
var arrayVolley = [[Int]]()
init(){
self.arrayVolley = [[]]
}
Here is where I try to insert :
func addPoints(score : Int, x : Int, y : Int){
if (score > 11 || score < 0){ //11 will be translated as 10x
println("Error on score value")
}
else {
if (x>6 || y>6){
println("Out of array")
}
else{
arrayVolley[x][y]=score
}
}
}
And this is my main :
var i=0
var j=0
for i in 0...6 {
for j in 0...6{
println("Entrez le score")
var scoreinput=input()
var score = scoreinput.toInt()
distance.addPoints(score!, x: i, y: j)
}
}
Thanks a lot for your help in advance
Try to use append to add the integer to the array it is automatically the next idex. It think if the index was never used it gives an error e.g.
var test = [Int]()
test.append(2) // array is empty so 0 is added as index
test.append(4)
test.append(5) // 2 is added as max index array is not [2,4,5]
test[0] = 3 // works because the index 0 exist cause the where more then 1 element in array -> [3,4,5]
test[4] = 5 // does not work cause index for never added with append
or you intialize the array in the correct size, but it's need a size:
var test = [Int](count: 5, repeatedValue: 0) // [0,0,0,0,0]
test[0] = 3 //[3,0,0,0,0]
test[4] = 5 [3,0,0,0,5]
It hope this helps you if not please feel free to comment.

How to remove element of struct array in loop in golang

Problem
I have array of structs:
type Config struct {
Applications []Application
}
Note: Config - is a struct for json.Decode.
config = new(Config)
_ = decoder.Decode(&config)
In loop I have some condition and element deletion by key.
for i, application := range config.Applications {
if i == 1 {
config.Applications = _removeApplication(i, config.Applications)
}
}
func _removeApplication(i int, list []Application) []Application {
if i < len(list)-1 {
list = append(list[:i], list[i+1:]...)
} else {
log.Print(list[i].Name)
list = list[:i]
}
return list
}
But always I have "out of range" error. What is the best way to delete element by key from array of structs?
Quoting from the Slice Tricks page deleting the element at index i:
a = append(a[:i], a[i+1:]...)
// or
a = a[:i+copy(a[i:], a[i+1:])]
Note that if you plan to delete elements from the slice you're currently looping over, that may cause problems. And it does if the element you remove is the current one (or a previous element already looped over) because after the deletion all subsequent elements are shifted, but the range loop does not know about this and will still increment the index and you skip one element.
You can avoid this by using a downward loop:
for i := len(config.Applications) - 1; i >= 0; i-- {
application := config.Applications[i]
// Condition to decide if current element has to be deleted:
if haveToDelete {
config.Applications = append(config.Applications[:i],
config.Applications[i+1:]...)
}
}
You are getting this error because you are doing a loop over a slice with an inital range of X length that became X-n because you remove some elements during loop.
If you want to delete an item at a specific index from a slice, you can do it this way:
sliceA = append(sliceA[:indexOfElementToRemove], sliceA[indexOfElementToRemove+1:]...)
This question is a bit older but I haven't found another answer on StackOverflow which mentions the following trick from the Slice Tricks to filter a list:
b := a[:0]
for _, x := range a {
if f(x) {
b = append(b, x)
}
}
So in this case a function which deletes certain elements could look like this:
func removeApplications(apps []Applications) []Applications {
filteredApps := apps[:0]
for _, app := apps {
if !removeApp {
filteredApps = append(filteredApps, app)
}
}
return filteredApps
}
I think the simple way is
var (
slice = []int{1,2,3,4,5}
pos int
)
for _, i := range slice {
if i == 3 {
slice = append(slice[:pos], slice[pos+1:]...)
if pos > 0 {
pos = pos - 1
}
continue
}
pos++
}
here is...
https://play.golang.org/p/pK3B5Mii9k
To remove a particular slice from a struct we need to run a for-loop to find that particular slice and delete it
for example:
type variable struct {
Id int `json:"id"`
Message string `json:"message"`
}
var mssg = []variable{
{Id: 1, Message: "success"},
{Id: 2, Message: "failed"}
}
for i, a := range mssg {
if a.Message == "success" {
mssg = append(mssg[:i], mssg[i+1:]...)
fmt.Println(mssg)
}

Resources