网上的阿里二面的一道笔试题,实现destructuringArray函数,具有如下功能:
// destructuringArray( [1,[2,4],3], "[a,[b],c]" )
// result
// { a:1, b:2, c:3 }
网上解法不一且没有注释,为新人易懂,在此提供个人认为思路比较巧妙的2种解法,详见注释:
let a = f([1, [2, [4]], 3], '[a,[b,[d,e]],c]')
let b = f2([1, [2, [4]], 3], '[a,[b,[d,e]],c]')
console.log(a)// {a: 1, b: 2, d: 4, e: undefined, c: 3}
console.log(b)// {a: 1, b: 2, d: 4, e: undefined, c: 3}
// eval实现(关键词:解构、扁平化)
function f(arr, str) {
let html = `
// 构建自执行函数,因为return语句必须放在函数中
;(() => {
// 这里构建数组解构,形如:let ['a', 'b'] = [1, 2]
let ${str} = arr
// 这里相当于扁平化了数组,形如:多维数组['a', ['b']]扁平为一维数组['a', 'b']
let res = str.match(/[a-z]+/g)
let obj = {}
res.forEach((val, index) => {
// 使用eval获取上面解构过的变量值
obj[val] = eval(val)
})
return obj
})()
`
return eval(html)
}
// 递归实现(关键词:深拷贝)
function f2(arr, str) {
// 初次执行传入的是字符串,我们转为数组,而之后递归,传入的则都是数组
str = Array.isArray(str) ? str : JSON.parse(str.replace(/([a-z]+)/g, '"$1"'))
let obj = {}
str.forEach((val, index) => {
// 缓存该键对应的值
let res = arr[index]
if (Array.isArray(val)) {// 值为数组时,需要递归
// 将递归的值拷贝至最初的对象,思路类似深拷贝
Object.assign(obj, f2(res, val))
} else {// 值为数值时,直接赋值
obj[val] = res
}
})
return obj
}