How to write nice and clean Go package? [closed] - go

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I try to implement Sparse sets from this article in Go and make it into a package. In early implementation, the API is clean and minimal with only exported type Sparse and exported method Insert, Delete, Has, Union, Intersection, Clear, and Len, pretty much only basic sets operation.
Later on, I want to add new functionality, sets that can reserve an element automatically (lets call it AutoSparse). If Sparse have Insert(k int) which insert k into sets, AutoSparse have Reserved() reserved an available element. If I have {0 1 2 4 5} in AutoSparse, when i call Reserve() it must add 3, not 6 so now it become {0 1 2 4 5 3}. Here's the implementation at playground.
As you can see, in order to maintain which element to added into sets, it doesn't add new field in the struct and I want to keep it like that.
My Question is how to add that new functionality to my package without adding new exported type AutoSparse to keep the API clean and minimal?
This is what i already try:
I can use interface to hide implementation but function signature is different, one use Insert(k int), the other use Reserve(), even if I use name Insert() it still different, or should I use Insert(k int) but didn't use k at all? it can but it's awkward.
I can't use the same struct to implement this because once you Use Reserve() to add element, you can't use Insert(k int) because it will messed up the reserved element, even Delete and Clear is different.

You can use k... int as parameter.
func (sparse Sparse) Insert(k... int) error {
if len(k) == 0 {
// first case
return nil
} else if len(k) == 1 {
// second case
return nil
} else {
return errors.New("Too many arguments")
}
}

Related

Compare two structs like array in golang [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 months ago.
Improve this question
I am trying to compare 2 structs of the array type in Golang in order to know if having struct1 obtained from web scrapping is equal to struct 2, which is data fetched from the database.
It is the way that I have thought to be able to know if there has been a change between the external web and my database.
The structs is:
type Exchange struct {
Name string `gorm:"Column:name" json:"name"`
Buy float64 `gorm:"Column:buy" json:"buy"`
Sell float64 `gorm:"Column:sell" json:"sell"`
}
The result after consult is from scrapping:
&[{Dólar 38.5 41 } {Euro 38.82 43.57 } {P. Argentino 0.05 0.35 } {Real 6.95 8.95 }]
From web
&[{Dólar 38.5 41} {Euro 38.82 43.57} {P. Argentino 0.05 0.35} {Real 6.95 8.95}]
My Code:
fmt.Println(exchanges)
dbExchanges := getExchangesFromDB()
fmt.Println(dbExchanges)
if exchanges == dbExchanges {
fmt.Println("is equal")
} else {
fmt.Println("no is equal")
}
fmt.Println("Struct equal: ", reflect.DeepEqual(exchanges, dbExchanges))
Result:
no is equal
Struct equal: false
In the first if you are comparing the memory address of the two variables instead of theirs values. In the second if clause (using reflect.DeepEqual) you are comparing their values.

How to sort array contain double value in Kotlin? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I have below kind of array,
val mArrayList: ArrayList<String> = ArrayList()
mArrayList.add("10-12 YRS")
mArrayList.add("2-3 YRS")
mArrayList.add("4-5 YRS")
mArrayList.add("7-10 YRS")
mArrayList.add("5-7 YRS")
I have the above kind of ArrayList and I want to sort this ArrayList.
How to sort this kind of array?
Can anyone please help?
In Kotlin, you have the sortedBy/sortBy methods to sort such a list. The first one returns a new list that is sorted, the second sorts the receiver list in-place.
The lambda you pass it allows you to extract the value you want to use for comparison.
For instance, you can use this to sort by the first integer in your elements:
val sorted = mArrayList.sortedBy { it.split("-").first().toInt() }
Or if you want to sort your list in place:
mArrayList.sortBy { it.split("-").first().toInt() }
In both cases, it.split("-").first().toInt() splits the string into 2 parts (before and after the dash), and converts the first part into an integer (which is comparable).
I believe, this is the sort you are looking for:
mArrayList.sortBy { it.split("-", limit = 2)[0].toInt() }
println(mArrayList) //[2-3 YRS, 4-5 YRS, 5-7 YRS, 7-10 YRS, 10-12 YRS]

Calculate difference between two numbers and get the absolute value [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I want to find the difference between two numbers in Go and the result should not be in "-".
Please find my code below:
dollarValue := 240000 - 480000
The result is "-240000". But my expected output is just "240000". Can anybody help on how to calculate the difference between these two numbers.
Your title is misleading. It should be states without negative instead of - operator.
Basically what you want to get is the absolute different between two numbers
You have two options:
Use if/else condition to return the positive result if the result is negative
Use math.Abs (need to convert from/to float)
Just implement your own method
func diff(a, b int) int {
if a < b {
return b - a
}
return a - b
}
and use it like this:
dollarValue := diff(240000, 480000)

golang why don't we have a set datastructure [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
The community reviewed whether to reopen this question 9 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I'm trying to solve "The go programming lanaguage" exercise #1.4 which requires me to have a set. I can create a set type but why doesn't the language come with one ? go, having come from google, where guava also originated, why didn't the language designers opt for adding support for fundamental data structures ? why force your users to create their own implementations for something so basic as a set ?
One reason is that it is easy to create a set from map:
s := map[int]bool{5: true, 2: true}
_, ok := s[6] // check for existence
s[8] = true // add element
delete(s, 2) // remove element
Union
s_union := map[int]bool{}
for k, _ := range s1{
s_union[k] = true
}
for k, _ := range s2{
s_union[k] = true
}
Intersection
s_intersection := map[int]bool{}
if len(s1) > len(s2) {
s1, s2 = s2, s1 // better to iterate over a shorter set
}
for k,_ := range s1 {
if s2[k] {
s_intersection[k] = true
}
}
It is not really that hard to implement all other set operations.
Partly, because Go doesn't have generics (so you would need one set-type for every type, or fall back on reflection, which is rather inefficient).
Partly, because if all you need is "add/remove individual elements to a set" and "relatively space-efficient", you can get a fair bit of that simply by using a map[yourtype]bool (and set the value to true for any element in the set) or, for more space efficiency, you can use an empty struct as the value and use _, present = the_setoid[key] to check for presence.
Like Vatine wrote: Since go lacks generics it would have to be part of the language and not the standard library. For that you would then have to pollute the language with keywords set, union, intersection, difference, subset...
The other reason is, that it's not clear at all what the "right" implementation of a set is:
There is a functional approach:
func IsInEvenNumbers(n int) bool {
if n % 2 == 0 {
return true
}
return false
}
This is a set of all even ints. It has a very efficient lookup and union, intersect, difference and subset can easily be done by functional composition.
Or you do a has-like approach like Dali showed.
A map does not have that problem, since you store something associated with the value.
Another possibility is to use bit sets, for which there is at least one package or you can use the built-in big package. In this case, basically you need to define a way to convert your object to an index.

Remove slice element and reinitialize slice [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
What is the correct way to remove an item from a slice in GO?
Also, what is the correct way to reinitialize a slice i.e. completely empty it but still keep it?
I believe you are misunderstanding the nature of a slice. A slice is like an ArrayList in Java. It is backed by a regular array and grows/shrinks on demand. Operations on a slice have the same performance characteristic as those you would expect on an ArrayList.
Your question(s) would make more sense if slices were the LinkedList equivalent. For that, look up Package list.
Nevertheless, here's how to do this. Most comes directly from SliceTricks, but I think it's good practice on SO to not refer to links and provide the answer right here.
Way to remove an item from a slice
This is something that you can do in any programming language, in O(1) time, if you don't care about order. If you care about order, this is not going to work.
The idea is to overwrite the item you want to remove with the last item in the slice, then reduce the size of the slice by one.
arr := []string{ "allo", "hello", "bye", "chao" }
// delete "bye"
deleteIdx := 2
lastIdx := len(arr) - 1
// arr = { "allo", "hello", "chao", "chao" }
arr[deleteIdx] = arr[lastIdx]
// arr = { "allo", "hello", "chao" } ... "chao"
arr = arr[:lastIdx - 1]
You can do that in a single step (SliceTricks):
arr[deleteIdx], arr = arr[len(arr)-1], arr[:len(arr) - 1]
However, like mentionned in the SliceTricks article, some type of values will not be garbage collected if you don't nil them, as the backing array behind the slice still holds a reference to them. The solution is to nil them while doing the operation.
arr[len(arr)-1], arr[deleteIdx], arr = nil, arr[len(arr)-1], arr[:len(arr)-1]
// ^ Setting the deleted index to nil ^
This is all, of course, if you don't care about preserving order. If you do care, you will need to copy everything after deleteIdx starting over deleteIdx, which is O(n). If you find yourself doing this, think if there isn't a better datastructure for your needs.
// Copy everything from [deleteIdx+1 .. n) onto [deleteIdx .. )
copy(arr[deleteIdx:], arr[deleteIdx+1:])
// arr[n - 1] and arr[n] have the same value (n = len(arr) - 1)
arr[len(arr)-1] = nil
// re-slice to reference only the n-1 elements
arr = arr[:len(arr)-1]
Way to reinitialize a slice i.e. completely empty it but keep it
You can reinitialize a slice by re-slicing all its items out
// Keep everything from [0 .. 0), which means keep nothing
arr = arr[:0]
But there's a problem in doing this : as stated above, the backing array of the slice will still reference to the original items that were in the slice. What you should do instead is create a new slice and let this one be garbage collected.
The answer is manyfold:
You must realize that there is no slice without backing array and if you talk about a slice you always have to think about the backing array too. Musing about this a bit leads to...
The second part of the question "reinitialize a slice i.e. completely empty it but still keep it" is very unclear. Do not think about slices in this way. a = a[:0] reslices a to zero length while keeping the backing array.
For everything else: Have a look at the "official" Slice Tricks https://code.google.com/p/go-wiki/wiki/SliceTricks

Resources