Best practice to avoid float as key in JSON

xuanbao · · 459 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I have this struct which represents an item, for example a video, and it has elements that show up in different times. Elements can be a person or people, objects like car, etc.</p> <p>The struct for each item has the item ID, and a map which represents all the elements and when they show up. The map is mapping time-&gt;element, e.g. at 1.01 there is a car, and at 1:03 there is a dog. So the key is a float, but JSON of course only supports strings as keys.</p> <h2></h2> <p>What is the best practice to avoid float as key in JSON? Here are 2 ideas - which one is the better practice? or maybe option 3?</p> <p>1) convert the float64 to string</p> <p>2) or add a custom marshal</p> <h2></h2> <p>Here&#39;s the struct definition:</p> <pre><code>type Item struct { ID string `json:&#34;id&#34;` ... elements map[float64]*Element `json:&#34;elements&#34;` } </code></pre> <hr/>**评论:**<br/><br/>recurrency: <pre><p>Can you give a bit of context what data you are representing? In general I think of it as a smell for the precision reason whenever I end up with a float as a key</p></pre>therealfakemoot: <pre><p>This. <a href="/u/whaduppening" rel="nofollow">/u/whaduppening</a>, What is the exact nature of the problem you&#39;re trying to solve? You&#39;ve described <em>how</em> you want to solve it, but not <em>what</em> the problem really is. What does the float canonically represent? Why is the float the primary identifier for an &#34;Element&#34;? What <em>is</em> an Element?</p></pre>whaduppening: <pre><p>Thanks for your (and the others) feedback, knowing how to ask questions is an acquired skill I am working on. I edited the question, hope it&#39;s more clear now.</p></pre>therealfakemoot: <pre><p>After reading the edited question, here&#39;s my suggestion: don&#39;t use a map at all.</p> <p>It sounds like you&#39;re trying to describe a linear series of events, by timestamp. Why not use a <em>list</em> to the tune of <a href="https://gist.github.com/therealfakemoot/586bc5dfcfcd36d04b67dd130e0584de" rel="nofollow">this</a>. The events are ordered, so they should be in a sequential data structure.</p> <p>Edit: I left the Element type vague, but you should get the gist of it. Your final JSON payload is <em>nothing more</em> than a JSON list of Element values. That way, the internals of the Element type don&#39;t matter whatsoever during transport. Timestamps could be represented as strings, floats, positive integers counting upwards in milliseconds from timestamp 0, whatever.</p></pre>whaduppening: <pre><p>I thought of a list too, but the reason against was that it blocks from utilizing goroutines: Say I have 1 minute of video, and I want to have 30 samples, so array/map values. Ideally I&#39;d like to be able to split this over 30 goroutines. If it goes back into a map, each goroutine i will set its values in elements[i], but if it&#39;s an array, I&#39;ll want the array to be chronological, and then it&#39;s not so nice.</p></pre>therealfakemoot: <pre><p>That&#39;s okay. You CAN store the values post-processing and <em>before</em> JSON output in a Golang map using floats as keys, if you want. Then you can sort the intermediate values into chrono order and dump them into JSON after the video is done being processed.</p></pre>whaduppening: <pre><p>If I get correct what you are saying - dumping into JSON a map where keys are floats will require manipulating the keys to become string, which is my initial question.</p></pre>therealfakemoot: <pre><p>The top level JSON value would be a list, not a map. The top level list will contain objects/maps which would have a timestamp attribute among others.</p> <p>You&#39;ve got a bunch of goroutines all processing stuff and identifying things and when they appear, right? While you&#39;re processing them, store them all in a map. Once all processing is done, take that map and iterate over the keys, sort them, and then use the sorted list of keys to create a slice/array ( I&#39;m still fuzzy on the formal terminology tbh ), and then serialize that slice/array to JSON. Re-read my gist. There is no float key anywhere in the JSON marshalling structs.</p></pre>whaduppening: <pre><p>Thanks for your (and the others) feedback, knowing how to ask questions is an acquired skill I am working on. I edited the question, hope it&#39;s more clear now.</p></pre>JustinCampbell: <pre><p>Note sure what your data is, but you could change it to be:</p> <pre><code>[ { “key”: 1.23, “element”: { ... } } ] </code></pre> <p>I do this whenever working with collections of things that seem like k/v pairs in an API, since it’s much easier to add metadata to each item if needed.</p></pre>whaduppening: <pre><p>Thanks for your (and the others) feedback, knowing how to ask questions is an acquired skill I am working on. I edited the question with more explanation what the data is. </p> <p>Ideally &#34;1.23&#34; would be a key, as the timestamp.</p></pre>kapoof_euw: <pre><p>Would it not simply solve your problem if you&#39;d use time.Duration, which is basically an integer value, instead of a float? </p> <p>You can choose your precision as you like too, e.g. myDuration / time.Second (second precision).</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

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