A 同事:
[
{
"192.168.1.2": {
"Memory": "10%",
"HardDisk": "25"
},
"192.168.1.1": {
"Memory": "25%",
"HardDisk": "10"
}
}
]
B 同事:
[
{
"ip": "192.168.1.1",
"Memory": "10%",
"HardDisk": "25"
},
{
"ip": "192.168.1.2",
"Memory": "25%",
"HardDisk": "10"
}
]
我认为 B 写的是对的,但是不知道怎么科学地反驳 A。A 这么写好吗?不好的话 A 的问题在哪儿呢?
201
ClericPy 2019-12-16 23:23:38 +08:00
不说怎么用, 谁知道 A 和 B 怎么想的, 复杂度又不是只考虑取值
问 CTO 去 |
202
f056917 2019-12-16 23:26:57 +08:00
我是前端,用哪种看使用场景,但是大多数时候我都希望是 B
|
203
wuethan 2019-12-16 23:50:25 +08:00
团队开发,A 的写法就是在找麻烦
|
204
liukanshan 2019-12-17 00:08:35 +08:00 1
还是吃的太饱了
|
205
gowa 2019-12-17 00:51:02 +08:00
伙计,,A 是列表,,B 是列表内一个 map 对象啊。
如果是手动解 MAP 转 Java 实体类,你让 B 来解一下试试。。 不想找麻烦的一般都用 A, |
207
jismhxjr 2019-12-17 03:09:33 +08:00
站 B
|
208
ericgui 2019-12-17 04:33:24 +08:00
你们看来还是需要用 typescript
用了 ts,就不会有 A 这种沙雕写法出现了。 |
209
ericgui 2019-12-17 04:40:11 +08:00 1
包括但不限于 java,typescript,C#,C,C++等各种静态类型语言
凡是用动态语言的,都会出现类似 A 的奇葩 |
210
lele2019 2019-12-17 05:52:24 +08:00
大部分情况下是 B 方法,不过还是要考虑使用场景,或许你们的场景可能用 A 方法更合适。。要不怎么有这种争论呢。!
|
211
nifury 2019-12-17 06:09:14 +08:00
@ericgui 但是 A 这样有什么问题吗? A 虽然反直觉但是一样可以反序列化成 Map<String, Data>呀,而且查询还方便
|
212
xcstream 2019-12-17 06:15:17 +08:00
B 有顺序 信息量更大 A 方便查找
|
213
yukiloh 2019-12-17 07:26:21 +08:00 via Android
ip 做 k 怎么拿…
|
214
matepi 2019-12-17 08:29:06 +08:00
单纯拿 ip 查东西的话显然是 A 啊
ip 当然是要拿来当 key 查,又不用有序 但是你们如果有进一步的类似 ip 要变、通用反射框架必须值化之类的需求另说 |
215
dengtongcai 2019-12-17 08:33:48 +08:00 via iPhone
b 规范,如果一种特定场景,a 才考虑,但是一般是 b
|
216
vuevue 2019-12-17 08:44:23 +08:00 via Android
A 吃太饱了
|
217
J2s 2019-12-17 08:46:19 +08:00
用 A 的地方能用 B,用 B 的地方有时候用不了 A
|
218
fatpower 2019-12-17 08:47:13 +08:00
B 有疑问?
|
219
kokutou 2019-12-17 08:48:08 +08:00
站 B
|
220
happilylb 2019-12-17 08:49:28 +08:00 via Android
我的小米 9 屏幕指纹版早上醒来发现用不了然后去设置密码里面看指纹解锁消失了……才用一个月。。
|
221
waterlaw 2019-12-17 08:49:34 +08:00 via Android
选 B, 同一实体尽量使用相同结构,A 也有他的使用场景
|
222
mmixxia 2019-12-17 08:54:57 +08:00
B 的列表是同构的。解析的话代码会简单很多,而且易用。
|
223
c0011 2019-12-17 09:00:25 +08:00
如果使用数据是把 ip 当做索引,那么 A 这种是对的。
如果不是把 ip 当做索引,那么使用 A 的时候,一样需要全部遍历一下。这样的话,A 这样属于增加复杂性,提前优化,肯定是不建议的。 |
224
CantSee 2019-12-17 09:08:14 +08:00
b 好[手动 dog]
|
225
Youngxj 2019-12-17 09:11:39 +08:00
我也喜欢 b
|
226
nnnToTnnn 2019-12-17 09:15:32 +08:00
A 可以解析不?
B 可以解析不? --------------------------- 如果都能解析,干嘛纠结到底选择 A 好还是选择 B 好? 反正我是一个写前端的,写啥我都能解析,实在不行我就在 ts 里面搞个实体把你们这群后台的人给隔离开,自己写适配器 [doge] |
227
python 2019-12-17 09:16:00 +08:00 via Android
看来大家都喜欢 B
|
228
happilylb 2019-12-17 09:16:01 +08:00 via Android
@nnnToTnnn 哭哭,我的小米 9 屏幕指纹版早上醒来发现用不了然后去设置密码里面看指纹解锁消失了……才用一个月
|
229
nnnToTnnn 2019-12-17 09:17:24 +08:00
你们就是吃的太饱了,有这点时间纠结到底是选择 A 还是选 B,代码都写完好几遍了。
|
230
waphole 2019-12-17 09:18:42 +08:00
无脑站 B
|
232
waltcow 2019-12-17 09:23:13 +08:00
站 B
|
233
saltedFish666 2019-12-17 09:25:00 +08:00
一般情况我建议 B,但是 A 这种你不能说他错,A 的话查找起来可能快一点,但我觉得毫无意义
|
234
nnnToTnnn 2019-12-17 09:25:15 +08:00
@ericgui #209 无论是第一种还是第二种,这都是非常标准的 JSON 格式,至于前 /后台是用框架直接解析成 DTO 还是采用 JSON 库都很好解析(如果无法解析,那就是开发水平问题)。
一个 JSON 解析都要争论的话,那么是不是该反思一下工作是不是太饱和了? |
235
charlieputon 2019-12-17 09:25:40 +08:00 via Android
A 是沙币,这帖子竟然有 200+评论也是醉了。。
|
236
gimp 2019-12-17 09:25:45 +08:00
A 同事为什么要在对象外边再套个列表呢,取值多不舒服。
|
237
as5739 2019-12-17 09:25:57 +08:00
曾经我也写过 A,后来被前端小姐姐逼着改成 B 了。。
|
238
zxiso 2019-12-17 09:26:26 +08:00 via Android
对于后端来说,我比较喜欢 a,因为可以映射为 map k v 的形式,可以方便的判断某个 ip 是否存在,然后来取值。对于前端来说 a 形式不友好,很多控件都是只支持 b 形式,如果要用 a 形式还需要自己处理。总的来说的话,b 会更通用一些,而且一般用 b 的话前端不会怼你。
|
239
aoaione 2019-12-17 09:27:58 +08:00
作为前端需要返回 a 的情况比较少 一般都是需要 b 这种结构
|
240
HENQIGUAI 2019-12-17 09:29:20 +08:00
遇到一个需求,将数据按照某某属性分组,传给前端,前端直接显示
resultMap = problems .stream() .filter(i -> StringUtils.isNotEmpty(i.getTaskName())) .collect(Collectors.groupingBy(Problem::getTaskId, LinkedHashMap::new, Collectors.toList())); 然后遍历 resultMap.entrySet(),取出来 key 和 value 最后做成的东西就是长这个鬼样子 [ { "taskName" : "XXXXX", "list" : [ { "taskId" : "481", "taskDetailId" : 518}] }] 代码写的我都难受。。 |
241
dangyuluo 2019-12-17 09:29:23 +08:00
谁钱多听谁的
|
242
fancy111 2019-12-17 09:29:40 +08:00
苹果和梨子哪个好吃???
具体情况具体分析,A 的值可以直取,B 的需要遍历。但是 B 可以重复 IP,A 只适合定量。 |
243
nnnToTnnn 2019-12-17 09:31:19 +08:00
@zxiso
A 转 B ``` const data = [ { "192.168.1.2": { "Memory": "10%", "HardDisk": "25" }, "192.168.1.1": { "Memory": "25%", "HardDisk": "10" } } ] const newData = [] Object.key(data[0]).forEach((key)=>{ newData.push({ ip: key, ...data[0][key] }) }) console.log(newData) ```` A 转 B 也很简单啊。 |
244
WebKit 2019-12-17 09:34:08 +08:00
如果后端返回 A,我会让他改成 B
|
245
shengchao 2019-12-17 09:34:54 +08:00
我是前端,后端给我的通常是 B,但有时候为了业务方便,我自己会写一个方法,变成 A 的形式。
用 A 的原因:有时候我有 Key,可以直接使用对应的 Value,不需要再次循环,比如这个 JSON 很大的时候。 ```json [ { "192.168.1.2": { "ip": "192.168.1.2", "Memory": "10%", "HardDisk": "25" }, "192.168.1.1": { "ip": "192.168.1.1", "Memory": "25%", "HardDisk": "10" } } ] ``` |
246
z1154505909 2019-12-17 09:36:21 +08:00
A 这种我怕我会被公司前端打死
|
247
sirius1024 2019-12-17 09:36:42 +08:00
A 唯一的好处是 Key 永远不可能重复。
|
248
gitopen 2019-12-17 09:37:16 +08:00
一句话:插入 mongodb 时 key 不能有`.`啊
|
249
mayufo 2019-12-17 09:37:48 +08:00
站 B
|
250
pyfan 2019-12-17 09:40:27 +08:00
能先说一下你们公司这个 json 结构使用场景吗
|
251
crist 2019-12-17 09:45:43 +08:00
虽然 B 看起来比 A 要更加规范,但其实 A 方式更加利于查找,利于性能。
|
252
flashing 2019-12-17 09:46:18 +08:00
得有个 background 吧,不是简简单单怎么设计的问题,现在信息不全不太好判断出发点是什么。
话说 A 的方案本质上 json 是个 object,property 的名字可以是个 ip 地址这样有特殊符号的吗? |
253
qilishasha 2019-12-17 09:49:15 +08:00 via iPhone
b 扩展容易 很灵活 是标准的数据表写法(既然如此,加一个 id 怎么样😂)
|
254
lihongjie0209 2019-12-17 09:53:28 +08:00
@crist #251
什么叫性能? 在多大的数据量和什么样的硬件上会有明显的区别? 是否做过 profile? |
255
KuroNekoFan 2019-12-17 09:56:04 +08:00
json 数据应该自描述
|
256
yulgang 2019-12-17 09:56:22 +08:00
这该不会是从 zabbix 里拿出来的东西吧😂
|
257
dotw2x 2019-12-17 09:58:49 +08:00
哈哈 早上刚好看到个类似问题,有人吐槽微信小程序订阅消息接口返回值的反人类设计😀
小程序返回值: { errMsg: "requestSubscribeMessage:ok", zun-LzcQyW-edafCVvzPkK4de2Rllr1fFpw2A_x0oXE: "accept" } 大家期望的返回值 { errMsg:"requestSubscribeMessage:ok", data: [ { tmplId:"zun-fytytytrytrytr", result:"accept"}, { tmplId:"zun-fyrdrtdtrds5eu0", result:"reject"} ] } 详情: https://developers.weixin.qq.com/community/develop/doc/000028cf058e78010e590be2255400 |
258
iFlicker 2019-12-17 09:59:33 +08:00
转实体类少一个对象层级 ,一句话驳回去了
|
259
mizzle 2019-12-17 10:11:00 +08:00 via Android
很明显大多数人没有搞清楚字面量对象和 json 之间的区别。如果作为字面量对象,A 和 B 没有高下,只是使用场景不同。作为 json,B 更好。
|
260
unco020511 2019-12-17 10:23:46 +08:00
你这个 ip 是固定的还是不定的,相对来说如果是固定的 A 写法取值方便一些(相对),如果是不固定或者后期可能有更改,那就 B,反正 B 是万金油的,更灵活
|
261
unco020511 2019-12-17 10:24:48 +08:00
@unco020511 移动端开发角度
|
262
southsala 2019-12-17 10:26:17 +08:00
A 写的不是 Json,看 Json 定义 A collection of name/value pairs,不确定的数据怎么能做 name 呢
|
263
binux 2019-12-17 10:35:18 +08:00 1
|
264
darknoll 2019-12-17 10:37:16 +08:00
这种贴也能回这么多
|
265
DeWhite 2019-12-17 10:39:01 +08:00
团队作业肯定用 B,
|
266
cominghome 2019-12-17 10:41:45 +08:00
看需求,AB 都有各自的使用场景,大部分时候倾向于 B (前端同学估计会 100%选 B 2333 )
|
267
luoruiqing 2019-12-17 10:46:54 +08:00
选 B ! A 是 列表里一个元素?
|
268
palmers 2019-12-17 10:47:13 +08:00
我认为不存在对错, 将这两种数据结构放入具体的业务场景中 然后比较两种结构的优缺点个数就出来了
|
269
HanMeiM 2019-12-17 10:52:47 +08:00
第一眼肯定是选 B
但是具体情况下选 A 也没问题 |
270
kedron 2019-12-17 10:54:39 +08:00
@DOLLOR 前端会知道 192.168.1.2 和 192.168.1.1 这个两个 IP 吗?要是还有其他不同的很多个 IP 呢?
|
271
nnnToTnnn 2019-12-17 10:55:02 +08:00
@mizzle #259 依据是什么,作为 JSON 的定义,key 可以是任何一个字符串,作为 JSON 而言,两种方式并没有任何区别,区别的仅仅只是后台所谓的 Class 后台的 Class 和 JSON 没有任何关系。
不能因为大家解析 JSON 都是默认采用 Class 的字段名,所以认为 Class 必须和 JSON 字段对应吗? |
272
nnnToTnnn 2019-12-17 10:58:00 +08:00
所谓 Class 只不过有一个默认写好的 JSON 解析器帮你把 JSON 转换到了 Class 的实例,他能对应大多数的场景的一个通用的解决方案,当然还有部分场景无法覆盖的,一样可以重载一下,或者包装一下,都可以很好的解决这个问题。
----------------------------------------------- 问题的中心点不在于哪种格式,而是在于大家都采用一种格式,无论是 A 还是 B 确定一种就可以了,这样统一了,前后台都可以很好的包装一下解析器。或者写一个通用的解析方法 |
273
zhouzm 2019-12-17 11:02:46 +08:00
抛开 JSON 或 API 调用,原生开发里其实也有类型问题,接口开发中,返回对象集合到底采取数组形式还是键值对方式。
* 合理的做法是应该返回数组,array.length 就能判断对象数量,array(index) 获取对象。 但问题又来了,往往会出现对象有 name 属性,需要直接依据 name 方便的读写对象 * 通常的做法是另外提供一个接口方法,根据 name 返回对象的 index。 根据这个思路,其实 A 需求是存在的,但实现的方法应该是在 B 的基础上,再额外增加一个 key -> index 的键值对象做快速查询。 |
274
no1xsyzy 2019-12-17 11:11:00 +08:00
Twitter API 表示每个 Tweet 的时候用的是 A
实际上是用来表示 “无限延续的部分列表” 的唯一途径 |
275
no1xsyzy 2019-12-17 11:20:46 +08:00
@codeismylife #11 不存在任何标准说 A 不行。
@sagaxu #10 那么混杂一下: Map<String, Message>,message 带 ip 字段 我可能上面有点说错了,Twitter 是这种(还包括事事参考 Twitter 的 Pocket ) |
276
akakidz 2019-12-17 11:25:15 +08:00
作为一名前端,在没有特殊需求的情况下,都希望拿到的是 B
|
277
MisakaMikoto 2019-12-17 11:33:27 +08:00
AB 都可以,如果是列表展示,显然 B。用 A 打死
|
278
cquan 2019-12-17 11:36:45 +08:00
我虽然也不是大牛,但我也觉得 b 比较容易理解
|
279
codeismylife OP @yulgang 据 A 说,他见过 zabbix 里有这样的配置,所以他认为这么写没问题。
|
280
TimLang 2019-12-17 12:54:29 +08:00
大多数不理解争论的人是没有碰到过不讲理的前端。。
比如我们公司的前端小姐姐,最好一个接口把所有要的数据都放在里面,她才不管什么接口的规范呢。 |
281
chenyu0532 2019-12-17 12:56:43 +08:00
测试用 A 正式用 B。。。这个吵啥。。。
是不是活儿太少了。。。 |
282
NoKey 2019-12-17 12:59:02 +08:00
A 通过页面给到 java 后台,java 后台如何自动解析?求大佬指导一下
|
283
watzds 2019-12-17 13:02:44 +08:00 via Android
A 的顺序没保证,A 能实现的 B 都能实现
|
284
yuanfnadi 2019-12-17 13:20:00 +08:00
interface ResponseA {
[ip: string]: { Memory: string; HardDisk: string; }; } interface ResponseB { ip: string; Memory: string; HardDisk: string; } const response: ResponseA = { '192.168.1.2': { Memory: '10%', HardDisk: '25', }, '192.168.1.1': { Memory: '25%', HardDisk: '10', }, }; const responseb: ResponseB[] = Object.keys(response).map(ip => ({ ...response[ip], ip, })); ts 有任何问题吗? |
285
mizzle 2019-12-17 14:08:38 +08:00
@nnnToTnnn 认为 B 更优的根据是作为 data exchange 格式, B 比 A 层级少, 且明确表示携带了数据的顺序信息.
|
286
TimPeake 2019-12-17 14:10:38 +08:00
之前我司有个 JAVA 经常写 A 现在坟头草已丈五 😉
|
287
mtdhllf 2019-12-17 14:12:29 +08:00
安卓要是看到 A 写的想骂人~
|
288
mht 2019-12-17 14:12:52 +08:00
写 js 客户端的话 A 没所谓
写 java flutter 之类的客户端的话 B 会舒服很多 |
289
yonoho 2019-12-17 14:20:17 +08:00
这么反驳:v2 网友几乎一致选择 B,这是民主决策
|
290
duanxianze 2019-12-17 14:23:59 +08:00
赞成 B
|
291
yulgang 2019-12-17 14:34:20 +08:00
@codeismylife
zabbix 返回来的数据类似同事 B 写法 https://www.zabbix.com/documentation/3.4/manual/api/reference/host/get |
292
houzhimeng 2019-12-17 14:35:20 +08:00
这个是 b 了
|
293
anyele 2019-12-17 14:59:52 +08:00 via Android
你们是手动写代码解析的? 为啥还有不同的格式??
|
294
xixixi 2019-12-17 15:09:00 +08:00
如果 ip 是不固定的,我选 B;
如果 ip 是固定的,我也选 B,谁知道以后 ip 会不会增加 |
295
tgich 2019-12-17 15:19:40 +08:00
java8stream 分完组之后的结果就是 A 这样
|
296
apaso 2019-12-17 15:29:13 +08:00 via iPhone
能写整齐 b 的谁会用 a 估计有更深的业务要问下原因
|
297
wqzjk393 2019-12-17 15:50:54 +08:00
@nnnToTnnn 之前学习的时候,我们老师说在代码里尽量不要出现对列表通过具体的一个序号进行索引,写的时候是爽了,维护起来能让人烦死
|
298
onion83 2019-12-17 16:47:11 +08:00
如果从使用方法上来看 A 比较优势,因为可以快速判断某个 key 在对象中是否存在, 而不需要遍历数组,前后端都可以。
但是 A 有浏览器的兼容性问题,例如 ["0":"0","100":"100","a":"a"] 某些版本的浏览器会自动帮你填充为 : ["0":"0","1":NaN,"2":NaN ... "99":NaN ,"100":"100","a":"a"] 这个坑刚踩完。 https://bugs.webkit.org/show_bug.cgi?id=170807 |
299
abccccabc 2019-12-17 17:36:11 +08:00
做接口的话,B,通用。
除此以外,A。因为这种方式利于性能。因为不知道里面的 key 有多少个。 |
300
a719114136 2019-12-17 17:49:33 +08:00 via Android
服务端用 A 省事,客户端用 B 省事
|