已知有一个对象数组
const newArr = [
{
"id": "111",
"editType": "name",
"label": "姓名",
},
{
"id": "222",
"editType": "phone",
"label": "手机号码",
},
{
"id": "333",
"editType": "shop",
"label": "门店",
},
{
"id": "dtdgdfg",
"type": "address",
"editType": "address",
"zone": {
"options": {
"province": {
"label": "省份",
},
"city": {
"label": "城市",
}
}
},
"detail": {
"label": "详细地址",
},
"validate": {
"required": true
}
}
]
现在有一个需求就是我们需要拿到该对象数组里面的label属性对应的值的集合,也就是下面的这个样子。
['姓名', '手机号码', '门店', '省份', '城市', '详细地址']
const isObject = (obj) =>{
return Object.prototype.toString.call(obj) === '[object,Object]'
}
const getLabels = (obj) =>{
const keys = Object.keys(obj)
let result = []
for(let i= 0; i < keys.length; i++){
if(keys[i] === 'label'){
result.push(obj[keys[i]])
} else if(isObject(keys[i])){
//如果对象里面又嵌套了一层属性(可能是数组或者对象),这里我们需要判断一下
if(Array.isArray(obj[keys[i]])){
//如果这里是一个数组的话,可以加别的判断,
} else {
result = [...result, ...getLabels(obj[keys[i]])]
}
}
}
return result
}
//最后在循环遍历一下原数组
let result = []
for(const item of newArr){
result.push(...getLabels(item))
}
当我这样写完以后,老大就看了一下我写的代码,说了一句,不够优雅,于是我又重新写了一下(QAQ),老大说,可以把for of循环单独写一个函数 用map来遍历,把getLabels里面的else if的逻辑单独抽离出来。
const isObject = (obj) =>{
return Object.prototype.toString.call(obj) === '[object,Object]'
}
const getLabels = (obj) =>{
const keys = Object.keys(obj)
let result = []
for(let i= 0; i < keys.length; i++){
if(keys[i] === 'label'){
result.push(obj[keys[i]])
} else if(isObject(keys[i])){
//如果对象里面又嵌套了一层属性(可能是数组或者对象),这里我们需要判断一下
result = [...result, ...resetGetLabels(obj[keys[i]])]
}
}
return result
}
//最后在循环遍历一下原数组
const resetGetLabels = (source) => {
//如果是数组的话,就循环遍历一下,当然,看一下原数组,更深层次是没有数组的,所以这个代码只在刚开始就运行一次,
let result = []
if(Array.isArray(source)){
source.map((item) =>
result = [...result, ...getLabels(item)]
)
} else if(isObject(source)) {
result = [...result, ...getLabels(source)]
}
return result
}
resetGetLabels(newArr)
不得不说,代码的确优雅。