V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
codeismylife
V2EX  ›  程序员

同事为了 JSON 怎么写吵起来了!请各位断案!

  •  
  •   codeismylife · 2019-12-16 14:42:11 +08:00 · 32884 次点击
    这是一个创建于 1798 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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 的问题在哪儿呢?

    342 条回复    2019-12-28 23:33:44 +08:00
    1  2  3  4  
    neverfall
        1
    neverfall  
       2019-12-16 14:46:59 +08:00
    B 的比较好,
    看使用场景,A 的虽然也不算错,但是 A 的理解起来会比较费劲。
    A 的场景还可以直接去重。。。
    tanranran
        2
    tanranran  
       2019-12-16 14:47:08 +08:00
    要是多一个 IPV6 怎么搞
    stoneabc
        3
    stoneabc  
       2019-12-16 14:48:14 +08:00   ❤️ 1
    看场景,有时候不那么规范反而会更好…
    多数情况还是 B。
    superrichman
        4
    superrichman  
       2019-12-16 14:48:40 +08:00
    数据能正确解析的话两种都没有问题, B 的好处是传输数据少几对括号.
    evilhero
        5
    evilhero  
       2019-12-16 14:48:45 +08:00 via Android   ❤️ 1
    如果用 ip 做键,意义不明,哪怕一眼就能看出是 ip

    何不折中一下,看 a 的写法,应该还有别的数据,那就把 b 的 ip 信息组外面再加一层
    Cbdy
        6
    Cbdy  
       2019-12-16 14:50:38 +08:00
    B 好一些,数据结构越简单越好
    DelayNoMore
        7
    DelayNoMore  
       2019-12-16 14:50:41 +08:00
    A 搞了嵌套,要写多一个循环。。
    lshero
        8
    lshero  
       2019-12-16 14:50:43 +08:00   ❤️ 13
    客户端看见 A 这种肯定要妈见打的
    maomaomao001
        9
    maomaomao001  
       2019-12-16 14:51:24 +08:00   ❤️ 4
    无论后端写成什么样,前端都是要要有个 ACL (Anti-Corruption Layer) 保证稳定性和扩展性 。

    最简单的,不要为了这么个问不到结果的问题吵架

    var d = [
    {
    "192.168.1.2": {
    "Memory": "10%",
    "HardDisk": "25"
    },
    "192.168.1.1": {
    "Memory": "25%",
    "HardDisk": "10"
    }
    }
    ]


    _.map(d[0],(v,k)=>{
    return {
    ip:k,
    ...v,
    }
    })

    三行代码搞定的问题,自己处理一下也没什么
    sagaxu
        10
    sagaxu  
       2019-12-16 14:53:34 +08:00 via Android   ❤️ 2
    A 是 Map<String, Message>,message 中不带 ip 字段
    B 是 List<Message>,message 带 ip 字段

    我更倾向于 B,使用更方便
    codeismylife
        11
    codeismylife  
    OP
       2019-12-16 14:54:10 +08:00
    @Cbdy @DelayNoMore @evilhero @lshero @neverfall @stoneabc @superrichman @tanranran 再劳烦各位,A 这样写没有别的深层含义,就是简单认为这样写没问题。我与各位想法一致,认为 A 是错的,但是我想知道,是否有什么规范直接指出 A 这样写不行?这样可以快速结束争论。
    optional
        12
    optional  
       2019-12-16 14:54:49 +08:00 via iPhone   ❤️ 1
    a 怎么反序列化,难道你们都是手动解析的?
    learnshare
        13
    learnshare  
       2019-12-16 14:54:58 +08:00   ❤️ 2
    通常不会使用不确定的内容作为字段名
    cloudyplain
        14
    cloudyplain  
       2019-12-16 14:55:00 +08:00   ❤️ 22
    A 在 java8 中会导致常量区快速堆满,因为一般 json 库认为 key 是有限的,设计规范也不建议 key 是一个随机值。
    vakara
        15
    vakara  
       2019-12-16 14:55:02 +08:00 via Android
    b, 看你返回的是求组,而且是有相关性的,为了后期更好扩展,比如数据大了分页,搜索的,都更有优势。
    rioshikelong121
        16
    rioshikelong121  
       2019-12-16 14:55:23 +08:00   ❤️ 13
    我个人不喜欢用内容去作为 key. 所以我选择 B.
    vakara
        17
    vakara  
       2019-12-16 14:55:26 +08:00 via Android
    @vakara s/求 /数 /g
    kera0a
        18
    kera0a  
       2019-12-16 14:55:40 +08:00 via iPhone
    b。
    a 用动态 ip 做 key,完全不适合客户端使用
    qq976739120
        19
    qq976739120  
       2019-12-16 14:56:44 +08:00
    一般都是 B 吧.a 可以做去重?
    codeismylife
        20
    codeismylife  
    OP
       2019-12-16 14:56:46 +08:00
    @maomaomao001 一看你就是个脾气好的前端,他们没吵,只是日常争论哈哈,不过呢,像 B 这样写应该更收前段欢迎吧?
    shintendo
        21
    shintendo  
       2019-12-16 14:57:53 +08:00   ❤️ 4
    先不说规范不规范。

    A 形式的数据一定能转成 B 形式,B 形式的数据却不一定能转成 A 形式(比如要求允许 ip 重复,或者要求有序),从这个角度也是用 B 好
    x66
        22
    x66  
       2019-12-16 14:57:58 +08:00   ❤️ 1
    不负责任的猜一下,A 应该是写 python 之类的动态语言的,而 B 多半是写 Java 的。
    sevenzhou1218
        23
    sevenzhou1218  
       2019-12-16 14:58:20 +08:00
    我猜,你们是写 php 的吧? 只有写 php 的在写 api 的时候对象和数组不分。
    codeismylife
        24
    codeismylife  
    OP
       2019-12-16 14:59:40 +08:00
    @x66 A 写过 GO……B 是 JAVA 的
    netnr
        25
    netnr  
       2019-12-16 14:59:44 +08:00
    选 B,标准的数据格式

    如果选 A,那么还可以继续改造

    {
    "192.168.1.2": "10%,25GB",
    "192.168.1.1": "25%,10GB"
    }

    如果说后续的扩展 一台机子有多个 IP,在加个 主机名称的字段,按照思维:主机名 → 多个 IP → 每个 IP 对于的内存 /硬盘,而不是 IP → 主机名 /内存、硬盘
    ai277014717
        26
    ai277014717  
       2019-12-16 15:00:32 +08:00
    A 的话转 model 可能要多写几步,B 很容易映射
    dp2px
        27
    dp2px  
       2019-12-16 15:00:52 +08:00
    如果是为了根据 ip 查询选 A,A 其实是 JSON 字典。一般用于展示的都是 B,B 才是符合面向对象的实体类。
    maomaomao001
        28
    maomaomao001  
       2019-12-16 15:01:08 +08:00
    @codeismylife 关键是 , 这个就和 讨论 rest 一样,我感觉就是在浪费时间 , 各种最佳实践都是随着时间的推移都会变化的, 我现在开发前端基本上更加倾向于 独立应用 (就是不完全依赖后端发过来的数据结构了) , 就写个转换层,以后自己扩展也好,或者万一哪一天 后端重构 数据结构大变也好, 就非常容易处理了
    Vegetable
        29
    Vegetable  
       2019-12-16 15:01:36 +08:00
    无脑 B
    dp2px
        30
    dp2px  
       2019-12-16 15:02:34 +08:00
    @dp2px 很显然查询一般是交给数据库的,所以毋容置疑选择 B,A 的使用场景我暂时想不到,可能根本就是个人独创的伪场景
    orzorzorzorz
        31
    orzorzorzorz  
       2019-12-16 15:02:38 +08:00
    我碰上这事一般直接找老大,硬技能在这道题上没用,效率第一。
    Hanggi
        32
    Hanggi  
       2019-12-16 15:03:18 +08:00   ❤️ 1
    很明显一个是 map 一个是 array。
    他们所对应的遍历方法也不同,array 遍历方便一点,各种辅助函数也很多,没有特殊要求一般是走 B。
    如果有根据键寻找值的操作,map 会方便些。

    但是两个都可以轻松实现互相转换,所以不存在对错。
    还是看具体情况了。
    AlisaDestiny
        33
    AlisaDestiny  
       2019-12-16 15:03:57 +08:00
    @codeismylife #11
    直接把这个帖子丢给 A 同事看就行了。
    finab
        34
    finab  
       2019-12-16 15:05:00 +08:00   ❤️ 1
    选 B 吧,B 能兼容 A,A 兼容不了 B

    @maomaomao001 这就是 JSON Object Mapper 做的事吧,基本所有的这样的库都带 map 方法,不用自己写
    FaceBug
        35
    FaceBug  
       2019-12-16 15:05:38 +08:00   ❤️ 5
    当 IP 重复怎么办,比如你们将来开了多个机房,每个机房的子网都是 192.168.1.0,数据要汇总到一起
    FaceBug
        36
    FaceBug  
       2019-12-16 15:06:49 +08:00
    把 KEY 再改造一次?机房+IP,每次解析还先把 key 拆成机房、IP 两部分?
    Cbdy
        37
    Cbdy  
       2019-12-16 15:08:13 +08:00   ❤️ 8
    @netnr 你还是太保守了,这样改造更方便:"192.168.1.2,10%,25GB;192.168.1.1,25%,10GB"

    什么?有异议?别浪费时间了! ACL 懂不懂?写个转换层不会吗?又不是不能用!
    sgiyy
        38
    sgiyy  
       2019-12-16 15:09:29 +08:00
    B。

    可以直接用数组的方法不够香吗?对于前后端都更方便点。
    hevi
        39
    hevi  
       2019-12-16 15:09:31 +08:00   ❤️ 1
    要是选 a 的话,我觉得不如:
    ```
    [
    ["192.168.1.1", "10%", "25"],
    ["192.168.1.2", "10%", "25"],
    ["192.168.1.3", "10%", "25"]
    ]
    ```
    (手动滑稽)
    qiaobeier
        40
    qiaobeier  
       2019-12-16 15:12:40 +08:00
    B 好,可读性更强,扩展性更好。
    reus
        41
    reus  
       2019-12-16 15:13:55 +08:00
    如果需要服务器端排序,那肯定 B
    buffzty
        42
    buffzty  
       2019-12-16 15:14:14 +08:00
    我们会写 b, 然后实际用的时候会再 map 一遍生成一个 ipMapDetail
    a 方式不通用,万一 2 个 ip 一样呢.万一有些 ip 是 0.0.0.0 呢
    Jealee
        43
    Jealee  
       2019-12-16 15:17:01 +08:00
    前后端的数据交互更倾向 B 一些。另外 A 应该不是个数组吧,一般 A 适合一些特殊的场景。比如说维护一个聊天室的用户对象,利用 key 的唯一性,用 uid 作为 key,userinfo 作为 value。利用 hasOwnProperty 判断 key 是否存在,同时存取时也十分方便( obj[uid])。用数组的话则更加麻烦一些
    DamonLin
        44
    DamonLin  
       2019-12-16 15:18:16 +08:00
    肯定是 B 了
    Raymon111111
        45
    Raymon111111  
       2019-12-16 15:20:54 +08:00
    A 是什么鬼
    qinfensky
        46
    qinfensky  
       2019-12-16 15:22:03 +08:00
    选 B,我见过几个同事写 A,我都忍不了,Key 不固定,要取值还要先遍历,烦。
    wendellup2018
        47
    wendellup2018  
       2019-12-16 15:22:23 +08:00
    没见过 a 这么约定的, java 解析 json 都直接定义一个实体对象让 fastjson 之类的自动解析。
    定义成 a 这样,只能手动解析了。
    yanlaz
        48
    yanlaz  
       2019-12-16 15:22:52 +08:00
    A 是 PHP 后端?
    lagoon
        49
    lagoon  
       2019-12-16 15:23:43 +08:00
    选 B 无可争议。

    换个角度,A 既然要把数据直接放到 key 的位置,那干嘛还要 Memory、HardDisk ?
    既然不要 key,那就全不要。既然要 key,那就要。

    想要就要,不想要的部分就不要,未免太任性了吧?

    从一致性的角度来说,都不好吧。
    wangyzj
        50
    wangyzj  
       2019-12-16 15:24:40 +08:00
    这完全是看需求
    大家默认理解只是一个列表
    肯定是 B
    dajj
        51
    dajj  
       2019-12-16 15:26:13 +08:00
    都行,谁负责谁决定
    CommandZi
        52
    CommandZi  
       2019-12-16 15:27:01 +08:00
    A 大概是 PHPer
    amon
        53
    amon  
       2019-12-16 15:31:24 +08:00
    找几个客户端同学去教训一下 A
    aydd2004
        54
    aydd2004  
       2019-12-16 15:34:26 +08:00 via iPhone   ❤️ 2
    大家都选 b ?如果只知道 ip,想调用里面的某个字段怎么办
    angryfish
        55
    angryfish  
       2019-12-16 15:35:12 +08:00
    用这样的思维,A 类似返回了一个 Map,B 类似返回了一个 List
    wuwukai007
        56
    wuwukai007  
       2019-12-16 15:37:58 +08:00   ❤️ 1
    A 类似 {200:{message:success}}
    B >> {code:200,message:success}
    arthas2234
        57
    arthas2234  
       2019-12-16 15:39:09 +08:00
    用 A 就别想着用 Java 来搞了
    superarm
        58
    superarm  
       2019-12-16 15:39:17 +08:00
    作为一个三年前端,我比较支持 B,简洁好用
    wvitas
        59
    wvitas  
       2019-12-16 15:40:25 +08:00
    A 其实也可以解析,但是吧,从方便的角度来说,我支持 B
    mayuko2012
        60
    mayuko2012  
       2019-12-16 15:40:38 +08:00
    有一个问题:如果想获取 192.168.1.2 的 disk 值,只能循环查找吗?
    EasonFan
        61
    EasonFan  
       2019-12-16 15:41:08 +08:00
    A 的后期兼容性可能会出现问题,要考虑将来是要 IPV6 的情况,但是 A 有个好处,类似 map,可以直接取某个 ip 的使用情况。
    Smilencer
        62
    Smilencer  
       2019-12-16 15:42:15 +08:00
    A 是什么鬼
    binux
        63
    binux  
       2019-12-16 15:43:02 +08:00
    @cloudyplain #14 就连 C++ 都能取 pair。这难道不是说明 java 垃圾吗?
    sardine
        64
    sardine  
       2019-12-16 15:47:26 +08:00
    感觉都是 json,没有对错,都能用,但是 B 可读性高,处理方便,尤其是这个 key"192.168.1.1"也要作为值处理的时候,A 的写法就会让我骂街了
    amundsen
        65
    amundsen  
       2019-12-16 15:49:37 +08:00
    看到的第一个问题就是,你怎么才能方便地获取 ip 值,其他问题就不用讲了
    netnr
        66
    netnr  
       2019-12-16 15:50:02 +08:00
    @Cbdy 老哥,还是你骚
    ily433664
        67
    ily433664  
       2019-12-16 15:50:57 +08:00
    肯定是 B 啊,如果是 A 的话,为什么不直接这样
    [
    ["192.168.1.2", "10%", "25"],
    ["192.168.1.1", "25%", "10"]
    ]
    bk201
        68
    bk201  
       2019-12-16 15:52:34 +08:00
    用 a 然后序列化为 map 吗?
    Cbdy
        69
    Cbdy  
       2019-12-16 15:52:57 +08:00
    @cloudyplain 一般 json 库是哪个 json 库?
    ccbikai
        70
    ccbikai  
       2019-12-16 15:53:25 +08:00
    当然是 B 了,A 这样写会被喷吧
    vimiix
        71
    vimiix  
       2019-12-16 15:53:54 +08:00
    根据 IP 拿数据的话,A 好,还去重。
    B 没感觉哪里好。
    shintendo
        72
    shintendo  
       2019-12-16 15:56:08 +08:00
    @aydd2004 查找啊
    kedron
        73
    kedron  
       2019-12-16 15:58:00 +08:00
    如果要遍历,把所有的 ip 取到,A 方案怎么做?
    icyalala
        74
    icyalala  
       2019-12-16 15:58:35 +08:00
    以后需要保证有序,分页展示,A 怎么保证有序?
    客户端用的时候,需要 Model 化,A 怎么把 ip 字段映射到 Model 里,重新遍历一遍吗?
    keepeye
        75
    keepeye  
       2019-12-16 16:00:08 +08:00
    虽然我自己偶尔用 A,方便做交差运算,大部分场景还是 B,所以还是推荐 B 吧
    Hoshinokozo
        76
    Hoshinokozo  
       2019-12-16 16:00:25 +08:00
    哈哈,本渣渣前端表示之前有一个任务后端就是用的 A 的方式,把我整懵了,最后那个项目前端逻辑变得极其复杂,我都不想再去碰了。。。另外我一直觉得 JSON 最好不要用数字做键名,因为那句话怎么说来着:‘代码主要是写给人看的,然后顺便给机器执行’,A 方式虽然后端可能会觉得在某些方面会比较简洁高效,但是对前端来说理解的成本会呈指数级上升。。( PS:哪位后端就是 PHP,我现在才知道原来 PHP 部分数组和对象的。。难怪我每次问他参数传啥的时候他都说传个 JSON,我:???)
    kemikemian
        77
    kemikemian  
       2019-12-16 16:01:21 +08:00
    看需求啊,给你中规中矩的遇到特殊需求也蛋疼,楼主不贴需求有主导嫌疑
    ChenStyle
        78
    ChenStyle  
       2019-12-16 16:07:20 +08:00
    推荐 B
    wu67
        79
    wu67  
       2019-12-16 16:08:42 +08:00
    a 的话, 万一单机多 ip 呢...
    515576745
        80
    515576745  
       2019-12-16 16:10:12 +08:00 via Android
    b 的可维护性和拓展性都好,并不是怎么简单怎么来吧
    cluulzz
        81
    cluulzz  
       2019-12-16 16:11:01 +08:00
    @sagaxu #10 A 是 List<Map<String,Message>>...
    DOLLOR
        82
    DOLLOR  
       2019-12-16 16:11:03 +08:00
    @kedron
    Object.keys({
    "192.168.1.2": {
    "Memory": "10%",
    "HardDisk": "25"
    },
    "192.168.1.1": {
    "Memory": "25%",
    "HardDisk": "10"
    }
    })
    >> ["192.168.1.2", "192.168.1.1"]
    ypzhou
        83
    ypzhou  
       2019-12-16 16:11:11 +08:00
    前端 我选 B
    securityCoding
        84
    securityCoding  
       2019-12-16 16:15:06 +08:00
    这 A 脑子进水了
    saulshao
        85
    saulshao  
       2019-12-16 16:16:21 +08:00
    我没见过 JSON 用一个可变的值当成 Key 的,所以 A 的写法格式上不能说错,但是这种写法很难形成一个稳定的格式,因为解析这个东西的假设是第一个属性的名字(key)实际上是某个(不存在的)属性的值。一旦发生针对这个的变更,后续的所有客户端的程序可能都会受到影响。
    因此,我推荐 B 的写法。
    yuxuan
        86
    yuxuan  
       2019-12-16 16:17:02 +08:00
    不带业务场景的讨论都是耍流氓 这玩意 还是看使用场景
    leisunlove
        87
    leisunlove  
       2019-12-16 16:17:39 +08:00
    前端 我会怼 A 让他改成 B
    shintendo
        88
    shintendo  
       2019-12-16 16:17:46 +08:00
    A 有一个很大的问题:万一 ip 可以为空怎么办?
    nianyu
        89
    nianyu  
       2019-12-16 16:18:10 +08:00
    前端 选 b
    xmge
        90
    xmge  
       2019-12-16 16:18:24 +08:00
    A 是 map 直接转 json

    B 是结构体(对象)转 json

    作为后端开发,我也喜欢 B。
    nnqijiu
        91
    nnqijiu  
       2019-12-16 16:18:45 +08:00
    内容不适合作为 key 吧,A 不规范
    dengshen
        92
    dengshen  
       2019-12-16 16:20:11 +08:00
    a:用数字符合做 key??? 呵呵呵, 明显是 b 方案要好!
    danbai
        93
    danbai  
       2019-12-16 16:21:13 +08:00 via Android
    ip 是个变量 应当放 V 值
    DOLLOR
        94
    DOLLOR  
       2019-12-16 16:23:44 +08:00   ❤️ 3
    JS 的 Object.entries 和 Object.fromEntries 就是专门用来处理这种转换的。

    //A->B
    Object.entries({
    "192.168.1.2": {
    "Memory": "10%",
    "HardDisk": "25"
    },
    "192.168.1.1": {
    "Memory": "25%",
    "HardDisk": "10"
    }
    }).map(([ip, value]) => ({
    ip,
    ...value
    }))

    //B->A
    Object.fromEntries([
    {
    "ip": "192.168.1.1",
    "Memory": "10%",
    "HardDisk": "25"
    },
    {
    "ip": "192.168.1.2",
    "Memory": "25%",
    "HardDisk": "10"
    }
    ].map(({ ip, ...rest }) => [ip, rest]))
    WytheHuang
        95
    WytheHuang  
       2019-12-16 16:24:39 +08:00
    选 B
    hyy1995
        96
    hyy1995  
       2019-12-16 16:26:05 +08:00
    虽然都能用,但我想绝大多数人都会选 B 的
    weizhen199
        97
    weizhen199  
       2019-12-16 16:26:57 +08:00
    b
    一般写成 A 这样,我只有重复内容才会
    wangkun025
        98
    wangkun025  
       2019-12-16 16:27:56 +08:00
    我选择 B
    mysunshinedreams
        99
    mysunshinedreams  
       2019-12-16 16:27:59 +08:00
    我感觉需要看使用场景,A、B 都有合适的使用场景。
    simenet
        100
    simenet  
       2019-12-16 16:28:35 +08:00
    又到了炫技的时候了。。
    1  2  3  4  
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4966 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 37ms · UTC 05:37 · PVG 13:37 · LAX 21:37 · JFK 00:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.