Go: pop from a map - dictionary

Is there an existing function where we can pop a (key,value) pair from a map in GO? I use the word pop instead of remove because a pop would re-arrange the elements after the index where the (key,value) was removed.
As an example the following code:
package main
import "fmt"
func main() {
mapp := make(map[int]int)
fmt.Println("before removal:")
for i := 1; i < 7; i++ {
mapp[i] = i
}
fmt.Println(mapp)
delete(mapp, 2)
fmt.Println("\nafter the removal:")
for i := 1; i < 7; i++ {
fmt.Println(i, mapp[i])
}
}
Produces the following output:
before removal:
map[1:1 2:2 3:3 4:4 5:5 6:6]
after the removal:
1 1
2 0
3 3
4 4
5 5
6 6
We notice that index location 2 is empty. I would like the output to be the following:
before removal:
map[1:1 2:2 3:3 4:4 5:5 6:6]
after the removal:
1 1
2 3
3 4
4 5
5 6
Is this functionality already in Go or would I have to implement it?

I think that you are misunderstanding what a map is and how it works. You should not see it as an "array with gaps", but as a classic hash table.
And to answer your question, when you use delete(), the value is deleted from the map, the problem is how you iterate over the "values" of the map.
To help you understand:
mapp := make(map[int]int)
fmt.Println(2, mapp[2])
will print
2 0
Why ? Simply because when the requested key doesn't exist, we get the value type's zero value. In this case the value type is int, so the zero value is 0.
So, you want to see if a key exists in the map before printing it and you have to use two-value assignment, like that:
for i := 1; i < 7; i++ {
if value, exists := mapp[i]; exists {
fmt.Println(i, value)
}
}
and it will print
1 1
3 3
4 4
5 5
6 6
Not really what you want, but the closer you can get directly with maps.
You can have a look at this blog post for more information and examples.
If you really want to have an array where you can remove values, see Verran's answer and use slices instead.

From the Go documentation:
When iterating over a map with a range loop, the iteration order is not specified and is not guaranteed to be the same from one iteration to the next.
From this, it follows that there would be no way to automatically move a value up one position to fill a gap, since the key can be in a different iteration position each time you look at the values and theres no guarantee that the value mapped to 2 will slide up to 1.
If you want to do something like this, you will have to manually shift everything down one key value, something like:
for key := 2; key < len(map)-1; key++ {
map[key] = map[key+1]
}
Alternatively, you could use slices and if you know the index you need to "pop", create a new slice that omits the value:
value := slice[2]
slice = copy(slice[:2], slice[2+1:])

Related

Gravityform easy calculation - but total is not beginning from 0

I have a pretty simple calculation in gravityform, but because I add +1 and +0.5 to what people are filling out in the input fields, then the total from the begining is showing a number instead of only 0.
Example:
Field A +1
Field B +0.5
Calculation Field A x B x 295. But because I add +1 and +0.5 to what people put in the input field, then the total from the beginning, shows 147,5. Because it calculate 1*.0.5*295 = 147,5.
But I want the total just to show 0 until people are filling out the input field.
How can I avoid this?
Your best bet for a code-based solution will probably be to use the gform_calculation_result filter and check a value of 1 or 0.5 and return 0 instead.
gform.addFilter( 'gform_calculation_result', function( result, formulaField, formId, calcObj ) {
if ( result == 1 || result == 0.5 ) {
result = 0;
}
return result;
} );
An alternate approach would be to use conditional statements right in the calculation formula, powered by our Gravity Forms Advanced Calculations plugin.
You could check if the field has a value and provide a formula for that and return 0 otherwise.
if ( F1 > 0 ):
F1 + 1
else:
0
endif;

Go determine number of word occurences on a string slice

Having a hard time trying to figure out how can I count the number of apps or words on a slice using the go-lang code I made.
Hoping someone could help me figure out how to count the number of occurence?
https://play.golang.org/p/KvgI-lCz_c6
package main
import (
"fmt"
)
func main() {
apps := []string{"one", "two", "three", "one", "four"}
fmt.Println("apps:", apps)
o := CountOccurence(apps)
fmt.Println("=== o: ", o)
}
func CountOccurence(apps []string) map[string]int {
dict := make(map[string]int)
for k, v := range apps {
fmt.Println(k, v)
dict[v] = k
}
// fmt.Println("=== dict: ", dict)
return dict
}
Outputs the following
apps: [one two three one four]
0 one
1 two
2 three
3 one
4 four
=== o: map[four:4 one:3 three:2 two:1]
PS: go strings.Count only counts a string, not a []string.
What you currently do is you gather the different elements and you assign their index to them. If a word occurs multiple times, the highest index will be assigned to it.
As you stated, you want to count the words. So instead of the index, assign 1 for new words (first occurrence), and if it's already in the map, increment its value by 1.
Since you can index a map with a non-existing key, in which case the result is the zero value of the value type of the map, which is 0 for int, it will tell you it was found 0 times (so far), so you don't even have to check if a key is already in there, just go ahead and increment it:
dict[v]++
So CountOccurrences() may look like this:
func CountOccurence(apps []string) map[string]int {
dict := make(map[string]int)
for _, v := range apps {
fmt.Println(v)
dict[v]++
}
return dict
}
Which will output (try it on the Go Playground):
apps: [one two three one four]
one
two
three
one
four
=== o: map[four:1 one:2 three:1 two:1]

Groovy collections - Finding an element that matches a condition

I have a groovy collections which is an array, containing value starting from 0 through 'n'. I need to find a particular array index when a series of conditions occured. And,I do not need to scan through every value of the array but can jump across pre-defined intervals. For example, look for the condition for every 10 values in the array. Can someone tell me a way to do this?
For example, I want to do somehting like this below
def alltimes = [0 . . . . . 10000]
def end_time = 10000
def time = 0
while(time <= end_time)
{
// check the condition for alltimes[time]
if(condition_satisfied){
println "condition satisfied at time ${time}"
break
}
time = time + 50
}
When i explored all available methods of array, i did not find any one which can allow to jump variables instead of just one as in methods each, eachwithindex.
Seems like I need to use metaclass and create a new method?
You can use find for this:
def allTimes = 0..10000
Closure<Boolean> checkCondition = { all, single ->
single > 300
}
​(0..10000).step( 50 )​.find { time -> ​checkCondition( allTimes, time ) }​
Which is ripe for currying:
def allTimes = 0..10000
Closure<Boolean> checkCondition = { all, single ->
single > 300
}
​(0..10000).step( 50 )​.find checkCondition.curry( allTimes )​

Set slice index using reflect in Go

I'm in Go, working with a reflect.Value representation of a slice. I have the following:
slice := reflect.MakeSlice(typ, len, cap)
If I want to get the ith value from slice, it's simple:
v := slice.Index(i) // returns a reflect.Value
However, I can't seem to find a way to set the ith value. reflect.Value has lots of setter methods, for example, if I had a map, m, the following is possible:
m.SetMapIndex(key, value) // key and value have type reflect.Value
But there doesn't seem to be an equivalent for slices. My one thought was that maybe the value returned from slice.Index(i) is actually a pointer somehow, so calling v := slice.Index(i); v.Set(newV) would work? I'm not sure. Ideas?
Figured it out! Turns out I posted this prematurely - my guess that slice.Index(0) returns a pointer was correct. In particular:
one := reflect.ValueOf(int(1))
slice := reflect.MakeSlice(reflect.TypeOf([]int{}), 1, 1)
v := slice.Index(0)
fmt.Println(v.Interface())
v.Set(one)
fmt.Println(v.Interface())
v = slice.Index(0)
fmt.Println(v.Interface())
prints:
0
1
1
(Here's runnable code on the go playground)
This might help:
n := val.Len()
if n >= val.Cap() {
ncap := 2 * n
if ncap < 4 {
ncap = 4
}
nval := reflect.MakeSlice(val.Type(), n, ncap)
reflect.Copy(nval, val)
val.Set(nval)
}
val.SetLen(n + 1)
// ...
val.Index(n).SetString("value") // Depends on type
Taken from a library I wrote a while back github.com/webconnex/xmlutil, specifically decode.go.

Why doesn't this "binding" code work as expected in JavaFX?

I am new to JavaFX. I am not able to understand why the code below doesn't work.
import javafx.util.Sequences;
def nums = [1..10];
var curr = 0;
var evenOrOdd = bind if (nums[curr] mod 2 == 0) "{nums[curr]} is an even number" else "{nums[curr]} is an odd number";
for (curr in [0..(sizeof nums -1)])
{
println("{evenOrOdd}");
}
I am getting
1 is an odd number
1 is an odd number
1 is an odd number
1 is an odd number
1 is an odd number
1 is an odd number
1 is an odd number
1 is an odd number
1 is an odd number
1 is an odd number
If I change the code to
import javafx.util.Sequences;
def nums = [1..10];
var curr = 0;
var evenOrOdd = bind if (nums[curr] mod 2 == 0) "{nums[curr]} is an even number" else "{nums[curr]} is an odd number";
for (i in [0..(sizeof nums -1)])
{
curr = i;
println("{evenOrOdd}");
}
I get the correct output:
1 is an odd number
2 is an even number
3 is an odd number
4 is an even number
5 is an odd number
6 is an even number
7 is an odd number
8 is an even number
9 is an odd number
10 is an even number
Clearly, the counter increment in the loop is not treated as a value change and the bound expression is not re evaluated.
Can anyone please explain the concept behind this behavior?
The for expression implicitly defines its iteration variable (that's why you didn't need to declare i in your second example). Even if there is already a variable with the same name, for will still create a new one for its scope. Your bind expression is bound to the curr variable outside of your for loop, not to the one inside your for loop. And the one outside of your loop doesn't change, so the bound expression will not change.
Example to demonstrate this behaviour of for:
var curr = 0;
var ousideCurrRef = bind curr;
println("Before 'for' loop: curr={curr}");
for (curr in [0..3])
{
println("In 'for' loop: curr={curr} ousideCurrRef={ousideCurrRef}");
}
println("After 'for' loop: curr={curr}");
This will print:
Before 'for' loop: curr=0
In 'for' loop: curr=0 ousideCurrRef=0
In 'for' loop: curr=1 ousideCurrRef=0
In 'for' loop: curr=2 ousideCurrRef=0
In 'for' loop: curr=3 ousideCurrRef=0
After 'for' loop: curr=0
Thus the curr outside the for loop won't change if you modify a variable of the same name inside the for loop.

Resources