How to create map variable from string literal in Golang? - string

I have a prepared map structure as a string literal. Notice, it is not a JSON! (look at commas in the last elements of blocks)
dict := `{
"ru": {
"test_key": "Тестовый ключ",
"some_err": "Произошла ошибка",
},
"en": {
"test_key": "Test key",
"some_err": "Error occurs",
},
}`
I want to transform this string to real value of map type (map[string]map[string]string). I need it for tests. Is it possible?

If this is just for testing, I would remove the "unneeded" commas from the source string and use JSON unmarshaling.
To remove the unneeded commas: I'd use the regexp ,\s*}, and replace it with a single }.
For example:
dict = regexp.MustCompile(`,\s*}`).ReplaceAllLiteralString(dict, "}")
var m map[string]map[string]string
if err := json.Unmarshal([]byte(dict), &m); err != nil {
panic(err)
}
fmt.Println(m)
Output (try it on the Go Playground):
map[en:map[some_err:Error occurs test_key:Test key] ru:map[some_err:Произошла ошибка test_key:Тестовый ключ]]

Related

Remove all characters after a delimiter in a string

I am building a web crawler application in golang.
After downloading the HTML of a page, I separate out the URLs.
I am presented with URLs that have "#s" in them, such as "en.wikipedia.org/wiki/Race_condition#Computing". I would like to get rid of all characters following the "#", since these lead to the same page anyways. Any advice for how to do so?
Use the url package:
u, _ := url.Parse("SOME_URL_HERE")
u.Fragment = ""
return u.String()
An improvement on the answer by Luke Joshua Park is to parse the URL relative to the URL of the source page. This creates an absolute URL from what might be relative URL on the page (scheme not specified, host not specified, relative path). Another improvement is to check and handle errors.
func clean(pageURL, linkURL string) (string, error) {
p, err := url.Parse(pageURL)
if err != nil {
return "", err
}
l, err := p.Parse(linkURL)
if err != nil {
return "", err
}
l.Fragment = "" // chop off the fragment
return l.String()
}
If you are not interested in getting an absolute URL, then chop off everything after the #. This works because the only valid use of # in a URL is the fragment separator.
func clean(linkURL string) string {
i := strings.LastIndexByte(linkURL, '#')
if i < 0 {
return linkURL
}
return linkURL[:i]
}

How to check if a string only contains numbers in Swift 2?

Before Swift 2 I used this extension to check if a string only is made out of numbers:
func isNumbersOnly() -> Bool {
let regexNumbersOnly = NSRegularExpression(pattern: ".*[^0-9].*", options: nil, error: nil)!
return regexNumbersOnly.firstMatchInString(self, options: nil, range: NSMakeRange(0, self.length())) != nil
}
but now with Swift 2 I get the error
Cannot invoke initializer for type 'NSRegularExpression' with an
argument list of type '(pattern: String, options:
NilLiteralConvertible, error: NilLiteralConvertible)'
Is there a better known way now? Thnx!
In Swift 2 NSRegularExpression "throws" so you have to use it with try.
Also you can't pass nil for options anymore: if you don't want to specify options, pass an empty array (same for firstMatchInString).
And self.length() should become self.characters.count.
Last note: if the goal is to determine if a String contains only numbers, and since you're naming it "isNumbersOnly", the resulting Boolean should be true if there's only numbers: it's currently the inverse. I've fixed this in my example.
Ignoring errors:
let regexNumbersOnly = try! NSRegularExpression(pattern: ".*[^0-9].*", options: [])
return regexNumbersOnly.firstMatchInString(self, options: [], range: NSMakeRange(0, self.characters.count)) == nil
With proper error handling:
do {
let regexNumbersOnly = try NSRegularExpression(pattern: ".*[^0-9].*", options: [])
return regexNumbersOnly.firstMatchInString(self, options: [], range: NSMakeRange(0, self.characters.count)) == nil
} catch let error as NSError {
print(error.description)
}
Instead of using regular expressions, you can use CharacterSets to check for the existence (or absence) of certain characters. To check if the string is only digits you can use the following:
extension String {
var isDigits: Bool {
if isEmpty { return false }
// The inverted set of .decimalDigits is every character minus digits
let nonDigits = CharacterSet.decimalDigits.inverted
return rangeOfCharacter(from: nonDigits) == nil
}
}
This method can be applied to any type of CharacterSet and, in my opinion, is a lot cleaner than using regex strings.
Swift 2 has adjusted the error-handling process; you should now try the call, not specifying an error and be prepared to catch an exception.
E.g.
do {
let regexNumbersOnly = try NSRegularExpression(pattern: ..., options: nil)
... etc ...
} catch _ {}
... given that you're electing not to handle error states.

How to check if substring of string's array match to patterns from other string array

I wonder if there is any groovy-way to check if substring of strings matches to patterns.
For example I have strings List (or array):
def Errors = ['File xyz cannot be created: No space left on device', 'File kjh has errors: some_error']
Then I have list of strings, for example def Patterns = ['Tests failed', 'No space left on device', 'Something goes wrong', ...some strings... ]
I would like to check if some elements of List Patterns are substrings of Errors elements .
In that example it should return true, because Patterns has No space left on device and Errors has 'File xyz cannot be created: No space left on device'.
I know how to write it very ulgy and not efficient by using two for loops and method contains, but I know that Groovy has much more powerfull built-in methods. I have tried with findAll(), but it doesnt worked at all.
Do you have any ideas? Is there any way to make it more clever?
Explicitly naming pattern and error:
patterns.find { pattern -> errors.find { error -> error.contains(pattern) } } // -> No space left on device
patterns.any { pattern -> errors.find { error -> error.contains(pattern) } } // -> true
depending on what/how many you want to find.
Or even shorter:
patterns.find { errors.find { error -> error.contains(it) } }
patterns.any { errors.find { error -> error.contains(it) } }

How do you inspect an Optional-String's length?

class PersonEntry: NSObject {
var firstName: String?
var lastName: String?
}
//This errors
if (self.person.firstName?.isEmpty) {
println("Empty")
}
//Compiler auto-correction is this
if ((self.model.firstName?.isEmpty) != nil) {
println("Empty")
}
I understand that optional chaining returns an optional type. So I suppose my question is, how do you unwrap an optional string, to inspect it's length, without risking a crash ?
I presume that if the property is nil then you want to consider it empty - in that case you can use the nil coalescing operator in combination with the first version of the if statement:
if self.person.firstName?.isEmpty ?? true {
println("Empty")
}
If firstName is nil, the expression evaluates to the right side of the coalescing operator, true - otherwise it evaluates to the value of the isEmpty property.
References:
Nil Coalescing Operator
Optional Chaining
Another trick.
var str: String?
str = "Hello, playground"
println(count(str ?? ""))

Golang : type conversion between slices of structs

This questions follows another question of mine.
I don't exactly get what is wrong with my attempt to convert res to a ListSociete in the following test code :
import (
"errors"
"fmt"
"github.com/jmcvetta/neoism"
)
type Societe struct {
Name string
}
type ListSociete []Societe
func loadListSociete(name string) (ListSociete, error) {
db, err := neoism.Connect("http://localhost:7474/db/data")
if err != nil {
return nil, err
}
res := []struct {
Name string `json:"a.name"`
}{}
cq := neoism.CypherQuery{
Statement: `
MATCH (a:Societe)
WHERE a.name = {name}
RETURN a.name
`,
Parameters: neoism.Props{"name": name},
Result: &res,
}
db.Cypher(&cq)
if len(res) == 0 {
return nil, errors.New("Page duz not exists")
}
r := res[0]
return ListSociete(res), nil
}
Is a []struct{Name string} different from a []struct{Name string json:"a.name" } ?
Or is a ListSociete different from a []struct{Name string} ?
Thanks.
You are currently dealing with two different types:
type Societe struct {
Name string
}
and the anonymous one:
struct {
Name string `json:"a.name"`
}
These two would be identical if it wasn't for the tag. The Go Specifications states (my emphasis):
Two struct types are identical if they have the same sequence of fields, and if
corresponding fields have the same names, and identical types, and identical tags.
Two anonymous fields are considered to have the same name. Lower-case field names
from different packages are always different.
So, you can't do a simple conversion between the two. Also, the fact that you are converting slices of the two types makes the conversion problematic. I can see two options for you:
Copy through iteration:
This is the safe and recommended solution, but it is also more verbose and slow.
ls := make(ListSociete, len(res))
for i := 0; i < len(res); i++ {
ls[i].Name = res[i].Name
}
return ls, nil
Unsafe conversion:
Since both types have the same underlying data structure, it is possible to do an unsafe conversion.
This might however blow up in your face later on. Be warned!
return *(*ListSociete)(unsafe.Pointer(&res)), nil
Playground Example: http://play.golang.org/p/lfk7qBp2Gb
So, after some tests, here's whats i found out :
A ListSociete defined as such...
type Societe struct {
Name string `json:"a.name"`
}
type ListSociete []Societe
is different from this :
type ListSociete []struct {
Name string `json:"a.name"`
}
This second solution works, whereas the first doesn't.
So I assume there really is no way to convert (directly without writing an explicit loop) between types with different tags ?
In that case, i'll definitely go with the loop, as using tags directly in types (cf. second solution above) would make my code unreadable and unreusable, also I really have no clue what I would be messing with using the unsafe conversion method. So thanks for confirming different tags made different types.

Resources