回答編集履歴

9

intにはならない、bool忘れ

2021/04/16 11:29

投稿

nobonobo
nobonobo

スコア3367

test CHANGED
@@ -190,7 +190,7 @@
190
190
 
191
191
 
192
192
 
193
- [https://play.golang.org/p/kbOCT3qMj3B](https://play.golang.org/p/kbOCT3qMj3B)
193
+ [https://play.golang.org/p/MFEcaerWzlP](https://play.golang.org/p/MFEcaerWzlP)
194
194
 
195
195
  ```go
196
196
 
@@ -216,13 +216,13 @@
216
216
 
217
217
  "itemType": "text",
218
218
 
219
- "x": "236",
219
+ "x": 236,
220
-
220
+
221
- "y": "145",
221
+ "y": 145,
222
-
222
+
223
- "fontSize": "20",
223
+ "fontSize": 20,
224
-
224
+
225
- "useKerning": "false"
225
+ "useKerning": false
226
226
 
227
227
  },
228
228
 
@@ -264,9 +264,9 @@
264
264
 
265
265
  switch v := s.(type) {
266
266
 
267
- case int:
267
+ case bool:
268
-
268
+
269
- return fmt.Sprintf("int(%d)", v)
269
+ return fmt.Sprintf("bool(%v)", v)
270
270
 
271
271
  case float64:
272
272
 

8

typo修正

2021/04/16 11:29

投稿

nobonobo
nobonobo

スコア3367

test CHANGED
@@ -186,7 +186,7 @@
186
186
 
187
187
  hogesの型をinterface{}にすれば任意のJSONのパースは完了します。
188
188
 
189
- 以下のように型スイッチを再的に組むことで各値にアクセスできます。
189
+ 以下のように型スイッチを再的に組むことで各値にアクセスできます。
190
190
 
191
191
 
192
192
 

7

やっと質問の意図をつかみました

2021/04/16 11:20

投稿

nobonobo
nobonobo

スコア3367

test CHANGED
@@ -177,3 +177,147 @@
177
177
 
178
178
 
179
179
  実行例: [https://play.golang.org/p/ERBnucspJha](https://play.golang.org/p/ERBnucspJha)
180
+
181
+
182
+
183
+ ## 任意のJSONを解釈したい場合
184
+
185
+
186
+
187
+ hogesの型をinterface{}にすれば任意のJSONのパースは完了します。
188
+
189
+ 以下のように型スイッチを再起的に組むことで各値にアクセスできます。
190
+
191
+
192
+
193
+ [https://play.golang.org/p/kbOCT3qMj3B](https://play.golang.org/p/kbOCT3qMj3B)
194
+
195
+ ```go
196
+
197
+ package main
198
+
199
+
200
+
201
+ import (
202
+
203
+ "encoding/json"
204
+
205
+ "fmt"
206
+
207
+ "strings"
208
+
209
+ )
210
+
211
+
212
+
213
+ const src = `{
214
+
215
+ "FirstName": {
216
+
217
+ "itemType": "text",
218
+
219
+ "x": "236",
220
+
221
+ "y": "145",
222
+
223
+ "fontSize": "20",
224
+
225
+ "useKerning": "false"
226
+
227
+ },
228
+
229
+ "Gender": {
230
+
231
+ "itemType": "circle",
232
+
233
+ "male": {
234
+
235
+ "x": "359",
236
+
237
+ "y": "162",
238
+
239
+ "width": "9",
240
+
241
+ "height": "9"
242
+
243
+ },
244
+
245
+ "female": {
246
+
247
+ "x": "373",
248
+
249
+ "y": "162",
250
+
251
+ "width": "9",
252
+
253
+ "height": "9"
254
+
255
+ }
256
+
257
+ }
258
+
259
+ }`
260
+
261
+
262
+
263
+ func walk(s interface{}) string {
264
+
265
+ switch v := s.(type) {
266
+
267
+ case int:
268
+
269
+ return fmt.Sprintf("int(%d)", v)
270
+
271
+ case float64:
272
+
273
+ return fmt.Sprintf("float64(%f)", v)
274
+
275
+ case string:
276
+
277
+ return fmt.Sprintf("string(%q)", v)
278
+
279
+ case []interface{}:
280
+
281
+ items := []string{}
282
+
283
+ for _, value := range v {
284
+
285
+ items = append(items, walk(value))
286
+
287
+ }
288
+
289
+ return fmt.Sprintf("[%s]", strings.Join(items, " "))
290
+
291
+ case map[string]interface{}:
292
+
293
+ items := []string{}
294
+
295
+ for key, value := range v {
296
+
297
+ items = append(items, fmt.Sprintf("%q:%s", key, walk(value)))
298
+
299
+ }
300
+
301
+ return fmt.Sprintf("{%s}", strings.Join(items, " "))
302
+
303
+ default:
304
+
305
+ panic("unkown type")
306
+
307
+ }
308
+
309
+ }
310
+
311
+
312
+
313
+ func main() {
314
+
315
+ var hoges interface{}
316
+
317
+ json.Unmarshal([]byte(src), &hoges)
318
+
319
+ fmt.Print(walk(hoges))
320
+
321
+ }
322
+
323
+ ```

6

実行例追加

2021/04/16 11:19

投稿

nobonobo
nobonobo

スコア3367

test CHANGED
@@ -173,3 +173,7 @@
173
173
  }
174
174
 
175
175
  ```
176
+
177
+
178
+
179
+ 実行例: [https://play.golang.org/p/ERBnucspJha](https://play.golang.org/p/ERBnucspJha)

5

追記の追記の追記

2021/04/16 08:08

投稿

nobonobo
nobonobo

スコア3367

test CHANGED
@@ -99,3 +99,77 @@
99
99
  ```
100
100
 
101
101
  としてmaleやfemaleの内容を取り出すことはできます。
102
+
103
+
104
+
105
+ ## 追記の追記の追記
106
+
107
+
108
+
109
+ JSONがこの例示のまま可変要素が無く、構造が安定していると仮定するなら、
110
+
111
+ このJSONを[JSON-to-Go](https://mholt.github.io/json-to-go/)に投げ込んでみましょう。
112
+
113
+
114
+
115
+ 以下のような結果が得られますので、「AutoGenerated」型の変数で受けることができると思います。
116
+
117
+ ```go
118
+
119
+ type AutoGenerated struct {
120
+
121
+ FirstName FirstName `json:"FirstName"`
122
+
123
+ Gender Gender `json:"Gender"`
124
+
125
+ }
126
+
127
+ type FirstName struct {
128
+
129
+ ItemType string `json:"itemType"`
130
+
131
+ X string `json:"x"`
132
+
133
+ Y string `json:"y"`
134
+
135
+ FontSize string `json:"fontSize"`
136
+
137
+ UseKerning string `json:"useKerning"`
138
+
139
+ }
140
+
141
+ type Male struct {
142
+
143
+ X string `json:"x"`
144
+
145
+ Y string `json:"y"`
146
+
147
+ Width string `json:"width"`
148
+
149
+ Height string `json:"height"`
150
+
151
+ }
152
+
153
+ type Female struct {
154
+
155
+ X string `json:"x"`
156
+
157
+ Y string `json:"y"`
158
+
159
+ Width string `json:"width"`
160
+
161
+ Height string `json:"height"`
162
+
163
+ }
164
+
165
+ type Gender struct {
166
+
167
+ ItemType string `json:"itemType"`
168
+
169
+ Male Male `json:"male"`
170
+
171
+ Female Female `json:"female"`
172
+
173
+ }
174
+
175
+ ```

4

typo-fix

2021/04/16 08:05

投稿

nobonobo
nobonobo

スコア3367

test CHANGED
@@ -74,11 +74,15 @@
74
74
 
75
75
 
76
76
 
77
+ ```
78
+
77
79
  - ルートオブジェクト
78
80
 
79
- - 子オブジェクト
81
+ - 子オブジェクト
80
82
 
81
- - 孫オブジェクト
83
+ - 孫オブジェクト
84
+
85
+ ```
82
86
 
83
87
 
84
88
 

3

追記の追記

2021/04/16 03:35

投稿

nobonobo
nobonobo

スコア3367

test CHANGED
@@ -59,3 +59,39 @@
59
59
  今のJSON構造を「UIのフォームレイアウト定義」すると以下の点に疑問があり意図が掴めません
60
60
 
61
61
  - itemType=circleに複数のmale、femaleを許容するのが不自然。
62
+
63
+
64
+
65
+ ## 追記の追記
66
+
67
+
68
+
69
+ JSONのツリー構造を「map[string]map[string]map[string]interface{}」で受けるとき、
70
+
71
+ 以下の構造を期待しますが、孫にオブジェクト以外が現れる現状のJSONデータは適合できません。
72
+
73
+ ルートがオブジェクト、子がオブジェクトという構造が守られていますが、孫はオブジェクトだったり数値だったり文字列だったりしているので、孫をオブジェクトとしてParseすることはできません。
74
+
75
+
76
+
77
+ - ルートオブジェクト
78
+
79
+ - 子オブジェクト
80
+
81
+ - 孫オブジェクト
82
+
83
+
84
+
85
+ 孫の型がばらついているので孫は「interface{}」でで受けるべきなのです。
86
+
87
+
88
+
89
+ その上で、
90
+
91
+ ```go
92
+
93
+ male := hoges["Gender"]["male"].(map[string]interface{})
94
+
95
+ ```
96
+
97
+ としてmaleやfemaleの内容を取り出すことはできます。

2

UIのレイアウト定義という解釈

2021/04/16 03:34

投稿

nobonobo
nobonobo

スコア3367

test CHANGED
@@ -53,3 +53,9 @@
53
53
  - FirstNameにValueに相当するものがないとか、
54
54
 
55
55
  - maleとfemaleが同時に存在するのは矛盾していて合わない気がします。
56
+
57
+
58
+
59
+ 今のJSON構造を「UIのフォームレイアウト定義」すると以下の点に疑問があり意図が掴めません
60
+
61
+ - itemType=circleに複数のmale、femaleを許容するのが不自然。

1

追記

2021/04/16 00:16

投稿

nobonobo
nobonobo

スコア3367

test CHANGED
@@ -11,3 +11,45 @@
11
11
 
12
12
 
13
13
  ご自身で書いている「map[string]map[string]interface{}」という型指定が正解だと思うのですが。
14
+
15
+
16
+
17
+ ## 追記
18
+
19
+
20
+
21
+ 「構造体を作らないとダメか」という問いは「どちらでも対応できます」が構造体を作るのがおすすめです。
22
+
23
+
24
+
25
+ 複雑な構造をGoのJSONで扱う方法はいくつか手法があります。
26
+
27
+ - json.RawMessageを使った多段階デコード/エンコード
28
+
29
+ - ommitを使った未使用フィールドの省略
30
+
31
+ これらを駆使して適切な構造体を定義してやるのがGoにとっての適切なやり方になると思います。
32
+
33
+
34
+
35
+ 質問の意図がつかめない原因は具体的に何をJSONで表現しようとしているのかがわからないためです。
36
+
37
+ 「私だったらこうします」というアドバイスができません。
38
+
39
+
40
+
41
+ アドバイスが必要ならJSON構造の具体的な意図を解説して欲しい。
42
+
43
+
44
+
45
+ - 各フィールドの値には具体的にどんな情報を載せたいのでしょうか?
46
+
47
+ - itemTypeが必要な理由はなんでしょうか?
48
+
49
+
50
+
51
+ 今のJSON構造は「個人の情報と解釈」すると以下の点に疑問があり意図が掴めません
52
+
53
+ - FirstNameにValueに相当するものがないとか、
54
+
55
+ - maleとfemaleが同時に存在するのは矛盾していて合わない気がします。