Trouble understand 2D array of strings in golfing

polaris · · 625 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<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 &lt;- 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&#39;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&#39;re getting the result you&#39;re getting because lines is <code>[][]string{{&#34;0 1 2 3 4&#34;}}</code> and not <code>[][]string{{&#34;0&#34;, &#34;1&#34;, &#34;2&#34;, &#34;3&#34;, &#34;4&#34;}}</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&#39;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) // =&gt; [[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])) // =&gt; prints []string fmt.Println(reflect.TypeOf(temp_element)) // =&gt; 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]] &gt;&gt;&gt; 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&#39;t have <code>[[1, 2], [3, 4]]</code> in your go program, you have <code>[[&#34;1 2&#34;], [&#34;3 4&#34;]]</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

625 次点击  
加入收藏 微博
0 回复
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传