<p>Edit: Excuse the bad title, safari auto correct golang to golfing</p>
<p>Here is my code</p>
<pre><code>var lines [][]string
var temp_element []string
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
temp_element := append(temp_element, scanner.Text()) // Scans in 0 1 2 3 4 into list [0 1 2 3 4]
lines = append(lines, temp_element) // Put list into a list [[0 1 2 3 4]]
// verify my assumptions
fmt.Println(lines) // [[0 1 2 3 4]]
fmt.Println(temp_element) // [0 1 2 3 4]
// verify no type conversion is going on
fmt.Println(reflect.TypeOf(temp_element)) // []string
fmt.Println(reflect.TypeOf(lines[0])) // []string
for _, row := range lines {
for _, element := range row {
// element is not individual string but rather the entire row
fmt.Println(element) // prints 0 1 2 3 4 <- I dont understand this result
fmt.Println(reflect.TypeOf(element)) // string
fmt.Println(lines) // prints [[0 1 2 3 4]]
}
}
}
</code></pre>
<p>As we can see, when I tried to iterate the element inside the list of list, it return the entire row instead. For example</p>
<p>I am expecting</p>
<pre><code> fmt.Println(element) to print
0
1
2
3
4
</code></pre>
<p>but it is printing</p>
<pre><code> 0 1 2 3 4
</code></pre>
<p>Why is this happening?</p>
<hr/>**评论:**<br/><br/>ChristophBerger: <pre><p>I think you just need to use ScanWords() instead of Scan(). The latter scans whole lines by default (unless you set a new SplitFunc).</p>
<p>[edit] And then your for loop should close after the append statement. </p></pre>seattledessert: <pre><p>The reason why I have </p>
<pre><code> for _, row := range lines {
for _, element := range row {
fmt.Println(element)
fmt.Println(reflect.TypeOf(element))
fmt.Println(strings.Fields(element))
fmt.Println(reflect.TypeOf(strings.Fields(element)))
fmt.Println(strings.Fields(element)[0])
fmt.Println(lines)
}
}
</code></pre>
<p>is to verify that each row consist of <code>[elem1 elem2......]</code>
and the entire list looks like <code>[[elem1 elem2.... ] [elem1 elem2....]]</code></p></pre>ChristophBerger: <pre><p>Apologies, my first comment was sent too quick and in fact is wrong. I had a closer look now and what I actually should have suggested is to add this line:</p>
<pre><code>scanner.Split(bufio.ScanWords)
</code></pre>
<p>just before</p>
<pre><code>for scanner.Scan() {
</code></pre>
<p>This sets the scanner's split function to one that splits by white space. (The default split function splits by line.) This way, if your stdin is</p>
<pre><code>0 1 2 3 4
</code></pre>
<p>the scanner returns separate tokens for each number.
I tested this in the playground: <a href="https://play.golang.org/p/qPP5J7HASu" rel="nofollow">https://play.golang.org/p/qPP5J7HASu</a>
If you run this, does it produce the expected result?</p></pre>seattledessert: <pre><p>Thanks <code>scanner.Split(bufio.ScanWords)</code> works just right, I think I was just confused on the by the way go represent the list of list string, thanks for the help. Greatly appreciated it.</p></pre>lespritd: <pre><p>To reiterate what ChristopherBerger said, you're getting the result you're getting because lines is <code>[][]string{{"0 1 2 3 4"}}</code> and not <code>[][]string{{"0", "1", "2", "3", "4"}}</code> like you assumed. If you <a href="http://play.golang.org/p/MQCz2G7IRM" rel="nofollow">explicitly set temp_element</a>, it works like you'd expect.</p></pre>seattledessert: <pre><p>Hmm, but when I print out the output for <code>lines</code> if I input multiple lines like</p>
<pre><code>1 2 3 4
5 6 7 8
</code></pre>
<p>I get</p>
<pre><code>fmt.Println(lines) // => [[1 2 3 4] [5 6 7 8]]
</code></pre>
<p>so each <code>lines</code> is indeed a list of list.</p>
<p>Moreover, I tried to sanity check myself with</p>
<pre><code>fmt.Println(reflect.TypeOf(lines[0])) // => prints []string
fmt.Println(reflect.TypeOf(temp_element)) // => prints []string
</code></pre>
<p>The problem is that when I iterate the list of list </p>
<p>The inner element turn out to be rows, which is unintuitive</p>
<p>So I did some verification in python</p>
<pre><code>a = [[1, 2], [3, 4]]
>>> for index_y in range(0, len(a)):
... for index_x in range(0, len(a[index_y])):
... print a[index_y][index_x]
...
1
2
3
4
</code></pre>
<p>Indeed python prints the each element as I expected. So in golang</p>
<pre><code> for _, row := range lines {
for _, element := range row {
fmt.Println(element)
}
}
</code></pre>
<p>Must have the same result too, since its the same algorithm.</p></pre>Justinsaccount: <pre><p>You don't have <code>[[1, 2], [3, 4]]</code> in your go program, you have <code>[["1 2"], ["3 4"]]</code></p></pre>seattledessert: <pre><p>Damn, thanks for catching that. Is it possible that go output list in <code>[elem1, elem2]</code> format with the comma? It just make it so much easier to debug.</p></pre>pizza-in-the-oven: <pre><p>Yep, this is one of the nuances in Go that people struggle with</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传