JS题目之数组数据拆分重组转成嵌套对象,让脑细胞活跃下

前言

下班的时候在群里看到一个小伙伴,在群里问了一道js的题,发现没人理会他;

来了兴趣就折腾了下,以下是解答过程,用的是ES6+的特性,在chrome跑的;

有兴趣的小伙伴可以瞧瞧~~谢谢

题目

解答
尽量注释,我分步骤解答

1:数组变形
格式:先拿到数据格式如下;

[ [ 'code', 'Zh' ],
  [ 'code', 'Cn' ],
  [ 'taobao', '.cn' ],
  [ 'taobao', '.com' ] ]


实现

这一步是拆开数据拿到我们想要的,比如基于大写字母,基于域名后缀;

因为数据格式是死的,所以正则也相对较为简单

let arr = ['codeZh', 'codeCn', 'taobao.cn', 'taobao.com'];
let arrSplit = arr.map(item => {
  if (item.indexOf('.')!== -1){
    return item.replace(/(\.)/g, ",$1").split(',')
  } else {
    return item.replace(/([A-Z])+/g, ",$1").split(',')
  }
})


console.log(arrSplit);


2:输出构建对象数据
格式:先拿到数据格式如下;

[ { code: { Zh: 'codeZh' } },
  { code: { Cn: 'codeCn' } },
  { taobao: { '.cn': 'taobao.cn' } },
  { taobao: { '.com': 'taobao.com' } } ]


实现

let arrGroup = arrSplit.map(item => {
  return {[item[0]]:{[item[1]]:item.join('')}}
})
console.log(arrGroup);


3: 实现符合的JSON
格式 : 先拿到数据格式如下;

{
   "code": {
      "Zh": "codeZh",
      "Cn": "codeCn"
   },
   "taobao": {
      ".cn": "taobao.cn",
      ".com": "taobao.com"
   }
}


实现
 

let resultObj = {};
for (let i = 0; i < arrGroup.length; i++){
  for (const [key, value] of Object.entries(arrGroup[i])) {
    resultObj[key] = {
      ...resultObj[key],
      ...value
    }
  }
}

console.log(resultObj);


完整代码

// 求数组转换成jso
//['codeZh', 'codeCn', 'taobao.cn', 'taobao.com'] 
// 输出
/*
{ 
  'code':{Zh:'codeZh',Cn:'codeCn'},
  'taobao':{'.cn':'taobao.cn},'.com':'taobao.com'
}
*/

const resultObj = {};
let arr = ['codeZh', 'codeCn', 'taobao.cn', 'taobao.com'];

let arrSplit = arr.map(item => (item.indexOf('.') !== -1 ? item.replace(/(\.)/g, ",$1").split(',') : item.replace(/([A-Z])+/g, ",$1").split(',')))

let arrGroup = arrSplit.map(item => ({ [item[0]]: { [item[1]]: item.join('') } }))

for (let i = 0; i < arrGroup.length; i++){
  for (const [key, value] of Object.entries(arrGroup[i])) {
    resultObj[key] = {
      ...resultObj[key],
      ...value
    }
  }
}

console.log(arrSplit);
console.log(arrGroup);
console.log(resultObj);


更优雅的姿势,来自评论
来自掘友Der: 正向预查询结合reduce组合对象;
代码的思路

reducer 主要接受两个参数,callback(回调函数)和initialValue(初始值)

回调函数接收4个参数:(累加器,当前值,当前索引,数组)

看懂reduce之后就好理解了,传入空对象作为初始值,正向预查捕获大写字母或小数点,

然后以这个为基准点进行切割字符串为数组,提取到两个变量里面

依次构建题目所需的格式了,至于最终会输出一个题目答案的对象,累加器的作用.

传入值是对象,所以针对遍历处理的行为都是处理同一个对象

const list = ['codeZh', 'codeCn', 'taobao.cn', 'taobao.com']
const result = list.reduce((map, item) => {
  const [head, tail] = item.split(/(?=[A-Z]|\.)/)
  map[head] = map[head] || {}
  map[head][tail] = item
  return map
}, {})
console.log(result)


来自掘友老姚
代码的思路

这个是replace的高级用法, replace可以传入正则捕获,回调函数包括如下(match,$1,$2),还有偏移量和字符串检测

内部的交换机制和组合与上个法子的差不多

const result = {} 
const list = ['codeZh', 'codeCn', 'taobao.cn', 'taobao.com'] 
list.join().replace(/([a-z]+)([A-Z\.][a-z]+)/g, (m, c0, c1) => { 
    result[c0] = result[c0] || {} 
    result[c0][c1] = m 
}) 
console.log(result)


总结
这个只是其中的一个解决姿势,肯定还有其他更优的法子;

仅供参考,不对之处请留言,会及时修正…
--------------------- 
作者:crper 
来源:CSDN 
原文:https://blog.csdn.net/crper/article/details/86530525 
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值