First argument to append must be slice; have struct - golang map - dictionary

Can't seem to use append for this case. Any help would be appreciated.
First argument to append must be slice:
package main
import (
"fmt"
)
type C struct {
value5 string
value6 string
}
type B struct {
value3 string
value4 C
}
type A struct {
value1 string
value2 B
}
type X struct{
key int
}
func main() {
letSee := map[X]A{}
letSee[X{1}]=A{"T",B{"T1",C{"T11","T12"}}}
letSee[X{1}]=append(letSee[X{1}], A{"L",B{"L1",C{"L11","L12"}}})
fmt.Println(letSee)
}
https://play.golang.org/p/R4gDO9MPBS

If in a map you want to store multiple values associated with the same key, the value type must be suitable for that. A struct isn't, but a slice is a perfect choice.
So change your value type to []A:
letSee := map[X][]A{}
letSee[X{1}] = []A{A{"T", B{"T1", C{"T11", "T12"}}}}
letSee[X{1}] = append(letSee[X{1}], A{"L", B{"L1", C{"L11", "L12"}}})
fmt.Printf("%+v", letSee)
Output (try it on the Go Playground):
map[{key:1}:[{value1:T value2:{value3:T1 value4:{value5:T11 value6:T12}}}
{value1:L value2:{value3:L1 value4:{value5:L11 value6:L12}}}]]

Related

Flow-js: How to create a variable consistent with an intersection of array and object

I have this valid flow-js definition for mysql :
declare type QueryResults = Array<Object> &{
insertId?: string | number,
affectedRows?: number,
changedRows?: number
};
And I've trying to create a variable that would be consistent with this definition. (You can try it here):
/* #flow */
type A = Array<Object>
type B = {
insertId?: string | number,
affectedRows?: number,
changedRows?: number
}
type C = A & B;
let a1: A = []
let a2: A = [{}]
let b1: B = {}
let b2: B = {insertId: 3}
let c: C
c = [] // Error, not complient with B
c.insertId = 5 // Error, not complient with A
Well, I just found out see here
c = {}.extend([])

Converting between equivalent Go maps

I was looking for a way to convert a map to another map, without copying key by key. Both maps have the equivalent key type (as demonstrated below).
The code below seems to do the job, but I'm wondering what kind of pitfalls there might be if I use this?
package main
import (
"fmt"
"unsafe"
)
type A string
var (
x A = "x"
y A = "y"
)
func main() {
a := map[A]string{}
a[x] = "242342"
a[y] = "1234"
b := convert(a)
fmt.Println(a[x])
fmt.Println(b["x"])
fmt.Println(a[y])
fmt.Println(b["y"])
}
func convert(in map[A]string) map[string]string {
return *(*map[string]string)(unsafe.Pointer(&in))
}

Is it possible to create a vector with references to lazy-static values?

The following code compiles:
let x = Regex::new(r"\d+").unwrap();
let y = Regex::new(r"asdf\d+").unwrap();
let regexes = vec![x, y];
But this code does not:
lazy_static! {
static ref X_PRIME: Regex = Regex::new(r"\d+").unwrap();
static ref Y_PRIME: Regex = Regex::new(r"asdf\d+").unwrap();
}
let regexes = vec![X_PRIME, Y_PRIME];
The error is:
error[E0308]: mismatched types
--> src\syntax\lex.rs:19:33
|
19 | let regexes = vec![X_PRIME, Y_PRIME];
| ^^^^^^^ expected struct `syntax::lex::lex::X_PRIME`, found struct `syntax::lex::lex::Y_PRIME`
|
= note: expected type `syntax::lex::lex::X_PRIME`
= note: found type `syntax::lex::lex::Y_PRIME`
Yes. lazy_static gives X_PRIME and Y_PRIME distinct types, but they both implement Deref<Regex>, so you could write:
let regexes = vec![&*X_PRIME, &*Y_PRIME];
// The * dereferences the values to a `Regex` type
// The & turn them back into references `&Regex`.
You could also just define another static:
lazy_static! {
static ref X_PRIME: Regex = Regex::new(r"\d+").unwrap();
static ref Y_PRIME: Regex = Regex::new(r"asdf\d+").unwrap();
static ref REGEXES: Vec<&'static Regex> = vec![&X_PRIME, &Y_PRIME];
}

Convert the dataype of VALUES in Maps Go language

I have a map in GO as :
var userinputmap = make(map[string]string)
and the values in it are of type :
[ABCD:30 EFGH:50 PORS:60]
Not that the 30,50,60 are strings over here.
I wish to have a same map but the numeric values should have float64 type instead of string type.
Desired output :
var output = make(map[string]float64)
I tried to do it but I get an error : cannot use <placeholder_name> (type string) as type float64 in assignment
You cannot do this by simple typecasting; the two maps have different representations in memory.
To solve this, you will have to iterate over every entry of the first map, convert the string representation of the float to a float64, then store the new value in the other map:
import "strconv"
var output = make(map[string]float64)
for key, value := range userinputmap {
if converted, err := strconv.ParseFloat(value, 64); err == nil {
output[key] = converted
}
}

Convert map[interface {}]interface {} to map[string]string

From a source I cannot influence I am given data in a map, which arrives as map[interface {}]interface {}.
I need to process the contained data, preferably as map[string]string (the data within is perfectly suitable for that).
I need to generate a list of the keys from the data as well, as those are not known beforehand.
Most similar questions I could find on the web say more or less, that this is impossible, but if my map is m, fmt.Println(m) shows the data is there, readable as map[k0:v0 K1:v1 k2:v2 ... ].
How can I do what fmt.Println is able to do?
A secure way to process unknown interfaces, just use fmt.Sprintf()
https://play.golang.org/p/gOiyD4KpQGz
package main
import (
"fmt"
)
func main() {
mapInterface := make(map[interface{}]interface{})
mapString := make(map[string]string)
mapInterface["k1"] = 1
mapInterface[3] = "hello"
mapInterface["world"] = 1.05
for key, value := range mapInterface {
strKey := fmt.Sprintf("%v", key)
strValue := fmt.Sprintf("%v", value)
mapString[strKey] = strValue
}
fmt.Printf("%#v", mapString)
}
Perhaps I misunderstand the question, but would this work?
m := make(map[interface{}]interface{})
m["foo"] = "bar"
m2 := make(map[string]string)
for key, value := range m {
switch key := key.(type) {
case string:
switch value := value.(type) {
case string:
m2[key] = value
}
}
}
// data is map[string]interface{}
form := make(map[string]string)
for k, v := range data {
form[k] = v.(string)
}

Resources