How to print out non-contiguous sections of the slice in Go? - go

Wondering if there is a way to print out non contiguous portions of slice in Gol?
Example:
words := []string{"Mary","had","a","little","lamb"}
and I want to print out "Mary" and "lamb" from the slice?
Something along the lines of:
fmt.Printf("%s\n", words[0],[5])
...which obviously this won't work... Is there a way ? :(
Thanks a lot!!

You can index into the slice, you just are doing it wrong.
fmt.Printf("%s %s\n", words[0], words[5])
Your syntax for indexing didn't work because the second variable was just the index stuff without words. Additionally your format string was wrong, a single %s which means Printf is only expecting a single argument after that. Gotta have one formatter per arg.

Related

Why is there a comma in this Golang struct creation?

I have a struct:
type nameSorter struct {
names []Name
by func(s1, s2 *Name) bool
Which is used in this method. What is going on with that comma? If I remove it there is a syntax error.
func (by By) Sort(names []Name) {
sorter := &nameSorter{
names: names,
by: by, //why does there have to be a comma here?
}
sort.Sort(sorter)
Also, the code below works perfectly fine and seems to be more clear.
func (by By) Sort(names []Name) {
sorter := &nameSorter{names, by}
sort.Sort(sorter)
For more context this code is part of a series of declarations for sorting of a custom type that looks like this:
By(lastNameSort).Sort(Names)
This is how go works, and go is strict with things like comma and parentheses.
The good thing about this notion is that when adding or deleting a line, it does not affect other line. Suppose the last comma can be omitted, if you want to add a field after it, you have to add the comma back.
See this post: https://dave.cheney.net/2014/10/04/that-trailing-comma.
From https://golang.org/doc/effective_go.html#semicolons:
the lexer uses a simple rule to insert semicolons automatically as it scans, so the input text is mostly free of them
In other words, the programmer is unburdened from using semicolons, but Go still uses them under the hood, prior to compilation.
Semicolons are inserted after the:
last token before a newline is an identifier (which includes words like int and float64), a basic literal such as a number or string constant, or one of the tokens break continue fallthrough return ++ -- ) }
Thus, without a comma, the lexer would insert a semicolon and cause a syntax error:
&nameSorter{
names: names,
by: by; // semicolon inserted after identifier, syntax error due to unclosed braces
}

How to convert byte array to string in Go [duplicate]

This question already has answers here:
How do I convert [Size]byte to string in Go?
(8 answers)
Closed 2 years ago.
[]byte to string raises an error.
string([]byte[:n]) raises an error too.
By the way, for example, sha1 value to string for filename.
Does it need utf-8 or any other encoding set explicitly?
Thanks!
The easiest method I use to convert byte to string is:
myString := string(myBytes[:])
The easiest way to convert []byte to string in Go:
myString := string(myBytes)
Note: to convert a "sha1 value to string" like you're asking, it needs to be encoded first, since a hash is binary. The traditional encoding for SHA hashes is hex (import "encoding/hex"):
myString := hex.EncodeToString(sha1bytes)
In Go you convert a byte array (utf-8) to a string by doing string(bytes) so in your example, it should be string(byte[:n]) assuming byte is a slice of bytes.
I am not sure that i understand question correctly, but may be:
var ab20 [20]byte = sha1.Sum([]byte("filename.txt"))
var sx16 string = fmt.Sprintf("%x", ab20)
fmt.Print(sx16)
https://play.golang.org/p/haChjjsH0-
ToBe := [6]byte{65, 66, 67, 226, 130, 172}
s:=ToBe[:3]
// this will work
fmt.Printf("%s",string(s))
// this will not
fmt.Printf("%s",string(ToBe))
Difference : ToBe is an array whereas s is a slice.
First you're getting all these negatives reviews because you didn't provided any code.
Second, without a good example. This is what i'd do
var Buf bytes.Buffer
Buf.Write([]byte)
myString := Buf.String()
Buf.Reset() // Reset the buffer to reuse later
or better yet
myString := string(someByteArray[:n])
see here also see #JimB's comment
That being said if you help that targets your program, please provide and example of what you've tried, the expect results, and error.
We can just guess what is wrong with your code because no meaningful example is provided. But first what I see that string([]byte[:n]) is not valid at all. []byte[:n] is not a valid expression because no memory allocated for the array. Since byte array could be converted to string directly I assume that you have just a syntax error.
Shortest valid is fmt.Println(string([]byte{'g', 'o'}))

Strange behavior when appending to a 2d slice

I am using a 2D slice of bytes to represent a bunch of lines, but when I append to one of the lines, I get some very strange behavior.
Here is an example:
package main
import (
"bytes"
"fmt"
)
func main() {
str := []byte("first line\nsecond line\nthird line")
values := bytes.Split(str, []byte("\n"))
fmt.Println("Before:")
fmt.Println(string(values[0]))
fmt.Println(string(values[1]))
fmt.Println(string(values[2]))
fmt.Println()
values[0] = append(values[0], []byte("-inserted text-")...)
fmt.Println("After:")
fmt.Println(string(values[0]))
fmt.Println(string(values[1]))
fmt.Println(string(values[2]))
}
I would expect the output of this program to be
Before:
first line
second line
third line
After:
first line-inserted text-
second line
third line
But instead the output is:
Before:
first line
second line
third line
After:
first line-inserted text-
inserted te
t-ird line
https://play.golang.org/p/iNw6s1S66U
Why is this happening and how can I fix it?
Interestingly, this doesn't happen if I don't use split and instead define values like so:
values := [][]byte{[]byte("first line"), []byte("second line"), []byte("third line")}
https://play.golang.org/p/pEflrhKLd4
The underlying storage is shared, so to get the effect you want, you would need to store copies of the slices returned from bytes.Split, rather than just the slices returned. When you append to the first slice returned, you're essentially stomping all over the following slices.
What you're doing is appending to the string, instead of appending to the array and thats overflowing the underlying data structure for the slice. Which is why the rest of the array is overwritten with the string you're appending.
To clarify (this may not always be the case):
the array values consists of 3 []byte blocks lined up consecutively. Each []byte block has a fixed length (based on the length of the string within it). So values[0] has a length of 10 (excluding '\n' or '\0'). Now if you try to append "-inserted text-" to that block, the characters will "flow" over into the consecutive block, values[1], replacing the characters within values[1] with the characters in "-inserted text-". That's why you see parts of those characters within values[1] and values[1].

How to print os.args[1:] without braces in Go?

When I tried to print command line arguments using
fmt.Println(os.Args[1:])
I got result like
[Gates Bill]
How can I get rid of the [] around the arguments? And Go seems to eat all the commas in the arguments, how can I get the output like
Last name, First name
Gates, Bill
You should use strings.Join for this. Try,
fmt.Printf("%s, Author of The Art of Computer Programming", strings.Join(os.Args[1:], ", "))
Join returns a string with ", " inserted between each argument.
The reason it's outputting the brackets is because you're passing a slice into the print command.
What you want to do is take each command and put them into a string to be printed as needed.
firstname := os.Args[1]
lastname := os.Args[2]
fmt.Println(lastname + ", " + firstname)
You should also take a look at the strings package as was pointed out by Chandru. There's a bunch of goodies in there to help with dealing with strings.
See: https://golang.org/pkg/strings/

How can I count the number of equal words between two strings?

How can I count the number of words that appear in two strings?
I'm thinking in something like this
let $nequalwords := count($item[text() eq $speech])
What is the best way to do this?
I thought to go with a two fors comparing word by word, but I don't know if there are a better way to do this.
How about splitting the strings on white space so that you end up with words, and then creating a sequence of the strings and removing those that are not distinct, i.e. those that appear in both strings, by then subtracting this from the count of all words you know how many words appeared in both strings. For example:
let $distinct-words1 := distinct-values(tokenize($string1, "\s+"))
let $distinct-words2 := distinct-values(tokenize($string2, "\s+"))
let $all-words := ($distinct-words1, $distinct-words2)
return
count($all-words) - count(distinct-values($all-words))
How about
count(tokenize($string1, "\s+")[. = tokenize($string2, "\s+")])
This is the number of words in the first string that also appear in the second string. Which might or might not be what you actually want. For example, if the two strings are "the more the merrier" and "the rite of spring", the answer will be 2.

Resources