5

之前遇到过这样一个问题,把下面一段服务器返回的文本

          Server: 192.168.31.92:2181
          zk_outstanding_requests   0
         zk_approximate_data_size   145237
                   zk_max_latency   417
                   zk_avg_latency   0
                       zk_version   3.4.8--1, built on 02/06/2016 03:18 GMT
                   zk_watch_count   22
         zk_num_alive_connections   12
    zk_open_file_descriptor_count   41
                  zk_server_state   follower
                  zk_packets_sent   87679
              zk_packets_received   79118
                   zk_min_latency   0
              zk_ephemerals_count   17
                   zk_znode_count   2193
     zk_max_file_descriptor_count   4096

转换为对象的形式。

这是一整段字符串,当然首先要按行分割为多段。设原始字符串为 str,则

let result = str.split('\n');

就获得了一个字符串数组。每个字符串头部都有空格,需要去除空格。

result = result.map(x => x.trim());

keyvalue 是放在同一段字符串里的,需要拆分开

result = result.map(x => x.split(/ {3}| :/)); // 这里取巧了,实际代码还是把第一行拆出来特殊处理比较好

这样就得到了一个类似

[
  [ "key1", "value1" ],
  [ "key2", "value2" ],
  [ "key3", "value3" ],
  // ...
]

的嵌套数组,可以看到,它正好是某对象 Object.entries 的结果。然而 JS 标准并没有提供 Object.entries 的反函数。

手写的话,很容易想到循环遍历赋值,这里有更简单的方法。首先把它转换为对象数组

result = result.map(([ key, value ]) => ({ [key]: value })); // 注意箭头后面的括号是必须的

得到

[
  { "key1": "value1" },
  { "key2": "value2" },
  { "key3": "value3" },
  // ...
]

把他们合并起来。记得怎样用 Array.object.concat 扁平化数组么?技巧类似

result = Object.assign(...result);

完整代码如下:

Object.assign(...str.split('\n').map(x => x.trim().split(/ {3}|: /)).map(([ key, value ]) => ({ [key]: value })))

PS: 我发现越短的文章看的人越多,每周积累一些小技巧也是很好的?

EDIT:新版 Firefox 中添加了 Object.fromEntries 作为 Object.entries 的反函数


CarterLi
1.3k 声望102 粉丝