Check if a value exists in a map in Golang - performance

I am searching for an efficient way to check if a value exists in Golang. The way I know is using a for loop/ range. Is there a better way to do the same?
Any help would be appreciated :)

When you index a map in Go you get two return values; the second one (which is optional) is a boolean that indicates if the key exists.
If the key doesn’t exist, the first value will be the default zero value.
Use second return value directly in an if statement.
m := map[string]float64{"pi": 3.14}
if v, found := m["pi"]; found {
fmt.Println(v)
}

There is no built in way to find out if a map contains a particular value. If you need this behaviour to be efficient, consider using an additional data structure to support it.
Note that although Java's Map provides containsValue, the documentation says:
This operation will probably require time linear in the map size for most implementations of the Map interface.
So, if you need an efficient implementation for a Java Map, you also need to provide one.
What "an efficient implementation" means changes based on what kind of data you're mapping. For example, if values are always unique, then maintaining a map[value]key is enough). If they're not, then something more principled is needed.

If you have rather big map and want to optimize value checking then add one more map nearly. Likemap[valueType]int. Then:
for k, v := range m {
values[v]++
}

Related

How to add a value to an existing hash without a key

I need to assign the numbers 0-100000 to a hash without giving a key.
Ruby uses Murmur as hash function. How can I add a value without having a key, like in C, letting it handle collision and other things. Is it possible? Can I give just the value to hash and let it evaluate the key, then insert to itself?
In a normal hashing operation, we have a hash function, and a table. We use value as the argument of the hash function, then we get a key in return. The value is inserted to the key location in the table (if a collision happens, double hashing or something else used).
Is it possible to do the same type of hashing in Ruby? Or am I stuck with default ways? Can I just throw the value into a function, then it evaluates the key, and inserts the value to the hash table or not?
Just store into the hash using the calculated hash of the key, rather than the key itself:
hash[hash_func(key)] = value
That is, instead of mapping key -> value directly, this maps hash_func(key) -> value. The implementation may pass your hashed key value through another hash function internally, but you needn't care about that.
However, in comments it now comes to light that you want to apply the hash function to the value, not any other key. In that case, just use a set and be done with it. Then, all you need to do is add values to the set:
s = Set.new
s.add(value)
There's no need to calculate the hash of anything; Set will take care of it for you.
In short, this seems to be a case of the XY Problem. You needed to store a set of values in a data structure (and presumably be able to check if those values were stored in an efficient manner). Instead of asking about this, you asked about hash functions and tables. If you had asked about what you really needed, instead of asking about something else that you thought you could use to solve the original problem, you would have had a useful answer much more quickly.
The common solution is to simply use the value as a key. Hence:
value = "xxx"
hash[value] = 1
This way, you clearly document that the actual values (all 1) of this particular hash are of no use, and you will get de-duplicated values. Hash will do the usual hashing internally, you don't need to worry about it at all.
I use 1 as value here, but the actual value is completely irrelevant. I don't use nil as that is the default return value of hash[nonexistant_value].
If your values are more complex, check out http://docs.ruby-lang.org/en/2.0.0/Hash.html for specifics about them.

how to enumerate array indices as odd and even numbers in parameters part of omnet.ini

I have this parameter as an array. The array is big, 100 cells. It is a parameter that can be initiated in omnet.ini file. The cells with even numbers should get value A and odd numbers should get value B. How can I do this in an automated manner?
Is there a way besides having all odd and even indices initiated one by one manually?
Wildcards can be useful but I do not know how to use them to separate odd and even indices.
Thanks.
You can access the actual module index with the index operator. Combining this with the conditional operator ?: you can easily define the value:
**.myModule[*].myParameter = index % 2 == 0 ? "A" : "B"
I'm not aware of any feature like this. There are a number of work-arounds you could use:
Provide two parameters and select the correct one in code
Use the volatile keyword (probably not appropriate here)
Put the entire thing in your .ini file
I'd personally implement the first approach, that way you can use the wildcard to pass both parameters ([*].myNode.parameterEven and [*].myNode.parameterUneven) and then set the correct values in your array in a for loop.
However, you could also use the volatile keyword in your NED file, see the manual for more details. However, this approach mostly works well if you have different parameters depending on which node you are assigning it to. For this case I think the first approach is better.
The last alternative is just putting the entire thing in your .ini file, which may be useful if you want to parameterize the array later.

using new vs. { } when initializing a struct in Go

So i know in go you can initialize a struct two different ways in GO. One of them is using the new keyword which returns a pointer to the struct in memory. Or you can use the { } to make a struct. My question is when is appropriate to use each?
Thanks
I prefer {} when the full value of the type is known and new() when the value is going to be populated incrementally.
In the former case, adding a new parameter may involve adding a new field initializer. In the latter it should probably be added to whatever code is composing the value.
Note that the &T{} syntax is only allowed when T is a struct, array, slice or map type.
Going off of what #Volker said, it's generally preferable to use &A{} for pointers (and this doesn't necessarily have to be zero values: if I have a struct with a single integer in it, I could do &A{1} to initialize the field). Besides being a stylistic concern, the big reason that people normally prefer this syntax is that, unlike new, it doesn't always actually allocate memory in the heap. If the go compiler can be sure that the pointer will never be used outside of the function, it will simply allocate the struct as a local variable, which is much more efficient than calling new.
Most people use A{} to create a zero value of type A, &A{} to create a pointer to a zero value of type A. Using newis only necessary for int and that like as int{} is a no go.

Complex datatypes as keys in maps in Go

I'm trying to create a map in Go that is keyed by big integers. Effective Go explicitly says that:
Structs, arrays and slices cannot be used as map keys, because equality is not defined on those types.
which makes sense. I could of course convert the big integers to strings and use the string as a key, but I'm looking for a more general solution here. Can I wrap my structure into something (an interface?) that implements an equality function and use that instead?
Example code that, of course, doesn't work:
package main
import (
"big"
"fmt"
)
func main() {
one1 := big.NewInt(1)
one2 := big.NewInt(1)
hmap := make(map[*big.Int] int)
hmap[one1] = 2
_, exists := hmap[one2]
fmt.Printf("Exists=%v\n", exists)
}
The rules about equality are going to change soon. From the Go 1 plan:
Go 1 will define equality on struct and array values composed from
fields on which equality is also defined (element-wise comparison).
It will remove equality on function and map values except for
comparison with nil. Go 1 will continue to exclude equality for
slices. (In the general case it is infeasible.)
However, even with this rules, you can not use *BigInt as key, since it contains a slice. Also note, that it is not possible in Go to write a custom equality operator (neither it is possible to override any other operator). But that's actually a strength of Go in my opinion - things are just simpler without it.
So, you will have to use strings for your keys. The strings however do not need to be formatted in decimal (or any other format) as long as you do not want to print them. So the fastest way is probably to use the Bytes() method (which will also discard the sign, make sure to include that separately in your string).

XPath: opposite of string() function?

In XPath it is possible to convert an object to string using the string() function. Now I want to convert the string back to an object.
I do understand it is not possible in some cases (for example for elements), because some information was lost. But it should be possible for simple types, like int or boolean.
I know, for numbers I can use number() function, but I want general mechanism which will work for any simple type variable.
Going to string is easy, because you've told it that you want a string.
Similarly, going to number is easy, because you've told it that you want a number.
But there is no generic way to say 'turn it back into x', because you haven't told it what x is.
(In other words, string() is like a cast like Java/C/C++/C# have. But there is no uncast.)
string() isn't an object serializer, so you can't deserialize.
Why do you want this? Perhaps there is another way of solving your problem.
If your object $x is the number 1234, then string($x) will be the string "1234".
If your object $x is a nodeset of 1000 XML elements, the first one being
<wibble><wobble>1<ping/>2</wobble>34</wibble>
then string($x) will be the string "1234".
The function is not a bijection, you can't have an inverse as many different values map to the same string.
In no language (that I know of) you can cast A to B and then call a magical function that reverts it back to whatever it was before you casted it.
The process of converting some data type into something else is always an unidirectional one - you lose the information what type it was before. That's because the new data type has no way of storing what it was before.
So, what are you trying to do? I strongly suspect that you ask this question because you are tackling a problem from the wrong end.

Resources