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

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.

Related

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)

What's the difference between "real" and "imaginary" parts of a complex numer in Go? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 4 years ago.
Improve this question
I was reading Go's documentation for the complex128 and complex64 data types when I came across something odd:
"complex128 is the set of all complex numbers with float64 real and imaginary parts."
And:
"complex64 is the set of all complex numbers with float32 real and imaginary parts."
More specifically:
"real and imaginary parts."
What's meant by this? How can a number be "real" or "imaginary"?
The question isn't dedicated to GoLang, to be honest.
Complex numbers are a mathematical concept.
Here is an example:
import (
"fmt"
"math/cmplx"
)
func main() {
fmt.Println(cmplx.Sqrt(-1))
}
Expected output:
(0+1i)
There is a package named "cmplx" to work with complex numbers. So Sqrt of cmplx is similar to math one, but it returns a complex number instead.
As you see, and output consists of 0 and 1i, and the last one is an imaginary part as we are not able to get a square root of "-1".
For complex numbers, see Wikipedia.
The only Go-specific topic is that the "complex" types are built-in in Go, so unlike in other languages you can perform basic operations on them without importing additional packages:
package main
import (
"fmt"
)
func main() {
c1 := 1i
c2 := 2 + 3i
fmt.Println(c1 * c1) // i^2 = -1
fmt.Println(c1 + c2) // i + (2+3i) = 2+4i
}
Playground.
For more advanced operations, you can use the math/cmplx package, similar to the math package for real numbers (as in being of habits' answer).

How to write nice and clean Go package? [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 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")
}
}

How is mapping done internally in golang? [duplicate]

This question already has answers here:
Meaning of underscore (blank identifier) in Go [duplicate]
(5 answers)
Closed 6 years ago.
Here is specific example
func main(){
m := make(map[string]int)
m["k1"] = 7
_, prs := m["k2"]
fmt.Println(prs)
}
What does "_" signifies here?
Rest is clear to me.
The _ means that you don't care about this particular return value.
Accessing a map index yield 2 values :
The value a that index, or the zero-value of the value type
A boolean indicating whether or not a value was at that index
In your case, prs will be the boolean.
This pattern is often used like this :
if _, found := m[key]; !found {
// Do something here to handle the fact that there is nothing at the index `key`
}
Map being a special type in Go, the second value is optional, so if you don't care about whether or not there is something in the map you don't have to check for it.
See dokumentation. Your statement:
_, prs := m["k2"]
is doing two things at the same time. A) Checking whether a key/value is present in the map and B) is retrieves the value. "prs" is a boolean indicating whether the value was present for the key "k2" or not.
Thus, if you only want to check if a key/value is present in the map and do not care to use the value, you can use the "_" to ignore the value and only use the "prs" boolean.

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