<p>I would like to use a slice with a number of dimensions which is only known at runtime. With append() I can only add new entries to the slice but I didn't find any way to add dimensions retrospecitively.</p>
<p>Background:
I would like to create a multidimensional database system based on cubes. My approach would be to use multidimensional slices as cubes. These cubes consist of dimensions. A user will be able to create new cubes and decide by himself which dimensions to add to the cube. I would have thought it's a good idea to use multidimeionsional slices for that. </p>
<p>Any help very much appreciated.</p>
<p><strong>Edit:</strong> Already solved by using the approach shown in that playground: <a href="https://play.golang.org/p/MvsVPYHrhp" rel="nofollow">https://play.golang.org/p/MvsVPYHrhp</a></p>
<hr/>**评论:**<br/><br/>neopointer: <pre><p>Do you mean something like this?</p>
<p><a href="https://play.golang.org/p/MvsVPYHrhp" rel="nofollow">https://play.golang.org/p/MvsVPYHrhp</a></p></pre>mentally_lazy: <pre><p>I had another approach in mind but this will work I think. Thank you!</p></pre>VerilyAMonkey: <pre><p>A multidimensional slice is nothing more than a slice of slices. Or a slice of slices of slices. Or... Etc.</p>
<p>But different numbers of dimensions are totally different types. With one of dimension n you do the [] operation n times and you get an element, with one of dimension more than n you'd get a slice, with one of dimension less than n you couldn't do it n times in the first place. They don't operate the same. So you can't choose on the fly. </p>
<p>So, you have about three options.</p>
<ol>
<li>Implement your own indexing scheme to use a single one dimensional slice as the backing data, but be able to access the correct parts of it with n it's as earthboundkid suggested. </li>
<li>Use a slice of interface{}'s, and type-assertions. </li>
<li>Reevaluate your approach. If by dimensions you mean attributes, and not all of them have all of them, maps might do you better than slices.<br/></li>
</ol></pre>mentally_lazy: <pre><p>Thanks for the detailed description. I'll go with option number 2.</p></pre>jerf: <pre><p>I'm not 100% sure what you're doing, but you may want to run the math on how large your slices are going to be. When you go multidimensional like that with a strict dense datatype, it doesn't take long before your slices are infeasibly large to work with, even on modern systems. They grow in size exponentially as you add dimensions. You may need to learn more about sparse representations.</p>
<p>A first cut for playing with would be a map that takes slices of integers as a key, though the operations for expansion are a bit funny too. But it would let you get your feet wet.</p></pre>mentally_lazy: <pre><blockquote>
<p>I'm not 100% sure what you're doing,</p>
</blockquote>
<p>There are systems on the market (e.g. Jedox Palo, IBM Cognos TM1, Infor Olap) that use a multidimensional architectures in order to store data. These systems hold all the data in memory. I want to buid a similar system in Go.</p>
<blockquote>
<p>it doesn't take long before your slices are infeasibly large to work with</p>
</blockquote>
<p>Yes, you are definitely right. Example data could look like this:</p>
<p>2016; 01; Revenue-Account; Legal-Entity-1;1000</p>
<p>2016; 01; Revenue-Account; Legal-Entity-2;1200</p>
<p>2016; 01; Revenue-Account; Legal-Entity-3;900</p>
<p>2016; 02; Revenue-Account; Legal-Entity-1;1300</p>
<p>2016; 02; Revenue-Account; Legal-Entity-2;1500</p>
<p>2016; 02; Revenue-Account; Legal-Entity-3;1700</p>
<p>This data would be represented by a 4 dimensional cube (the last column describes the value that is stored). There could be millions of those values. I would have planned to work with pointers to dimension elements in order to be efficient.</p>
<blockquote>
<p>You may need to learn more about sparse representations.</p>
</blockquote>
<p>Thanks for the advice!</p>
<blockquote>
<p>a map that takes slices of integers as a key,</p>
</blockquote>
<p>Good idea, I'll try that as well.</p></pre>epiris: <pre><p>He probably meant array of ints as map keys, they have to be comparable. Keep in mind you can use structs as map keys to pretty cheaply:</p>
<pre><code>type myKey struct{ a, b int; c string; d [2]byte }
key := myKey{1, 2, "c", [2]byte{1,2}}
</code></pre>
<p>The main benefit of structs is you can use mixed types in them as long as they are comparable. This can get unruly pretty fast but could be good to POC out your initial design. Ultimately you probably don't want to force this kind of data into higher level containers, specialized tree structures will likely be easier to work with.</p></pre>chewxy: <pre><p>Use package <a href="https://github.com/chewxy/gorgonia/tree/master/tensor" rel="nofollow">tensor</a>. The best part is you can do what <a href="/u/VerilyAMonkey" rel="nofollow">/u/VerilyAMonkey</a> suggests and implement it yourself using the exported <code>AP</code> data structure.</p>
<p>Here's an example:</p>
<pre><code>import . "github.com/chewxy/gorgonia/tensor"
func main() {
x := New(Of(Float64), WithShape(5, 4)) // 5 rows, 4 cols
x, _ = x.Hstack(New(WithBacking([]float64{1,2,3,4,5}), WithShape(5, 1)) // add an additional column
}
</code></pre>
<p>Have more than 2D? No problem</p>
<pre><code>x := New(Of(Int), WithShape(2,3,4)) // 2 "layers", 3 rows, 4 cols
</code></pre></pre>earthboundkid: <pre><p>Go doesn't support multidimensional slices, period. Fortunately, it's trivial to convert a 1-dimensional slice into an N-dimensional slice by writing a wrapper method. Just add and multiply to turn the x, y, z… coordinates into a flat coordinate.</p></pre>mentally_lazy: <pre><blockquote>
<p>Go doesn't support multidimensional slices</p>
</blockquote>
<p>I'm not sure what you mean with that. I use multidimensional slices already, - I just don't know if it's possible to define the number of dimensions on the fly or only at compile time.</p></pre>earthboundkid: <pre><p>That's not a multidimensional slice. It's a slice of slices. In a multidimensional slice, all rows are the same length, all columns are the same, etc. With a slice of slices, you could have the first slice be length 2, the next length 5, etc. They have no connection from one slice to the next. </p>
<p>For example, a slice of bytes is like a string. You might use a slice of slice of bytes to accumulate characters, and the first slice is h, e, l, l, o, and the second is w, o, r, l, d. </p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传