数组用的好,学习/面试/工作无烦恼

222 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第22天,点击查看活动详情

目录

今日题

  1. 题目
  2. 分析 昨日题
  3. 题目
  4. 答案
  5. 解析 结语

今日题

题目

找出2个数组中的对称差:

const a1 = ["HTML",1,"CSS",2,"JavaScript","anyScript","NodeJs","done"]
const a2 = ["HTML",1,"CSS",2,"NodeJs","anyScript","done"]

结果:

["JavaScript"]

分析

  • 数组无疑是我们接触最多的一个数组结构了
  • 对于今天这道题目的对称差,我们可以尝试遍历a1
  • 之后在a1中寻找a2内不存在的元素

昨日题

题目

验证对象中的属性值,将其转换为布尔值并存入数组中

const obj = {
    "key1": undefined,
    "key2": null,
    "key3": "",
    "key4": [],
    "key5": {},
    "key6": {
        "key1": "",
        "key2": "ok"
    },
    "key7": "ok",
    "key8": {
        "key9": {
            "key10": {
                "key11": "ok"
            },
            "key12": 0
        }
    },
    "key13": [{}],
    "key14": ["ok", "no", {
        "key15": ["ok"]
    }]
}

转换后:

[false, false, false, false, false, [false, true], true, [[[true], false]], [false], [true, true, [[true]]]]

答案

function toArray(obj) {
    const result = []
    if (!isNullValue(obj)) {
        result.push(false)
        return result
    }
    function isBaseType(param) {
        return !!param
    }
    function isObjectType(param) {
        return param instanceof Object
    }
    function isNullValue(param) {
        return Object.keys(param).length > 0
    }
    for (const key in obj) {
        const para = obj[key]
        if (isBaseType(para) && !(isObjectType(para))) {
            result.push(true)
        } 
        if(!isBaseType(para)){
            result.push(false)
        } 
        if (isObjectType(para) && !(isNullValue(para))) {
            result.push(false)
        } 
        if(isObjectType(para) && isNullValue(para)){
            result.push(toArray(para))
        }
    }
    return result  
}
const res = toArray(obj)
console.log(res)

解析

  • 对于本题中给出的对象,由于其嵌套层级没有规律,所以我们倾向使用递归来解决
  • 现在让我们来看分析解答:
const result = []       //(1)
if (!isNullValue(obj)) {
    result.push(false)
    return result
}
  • 首先,声明了一个result的数组(1)
  • 然后,是一个if的判断,调用了下面定义的isNullValue函数
    function isBaseType(param) {
        return !!param
    }
    function isObjectType(param) {
        return param instanceof Object
    }
    function isNullValue(param) {
        return Object.keys(param).length > 0
    }
  • 这三个函数都是用来判断的,它们的返回值都是一个boolean
  • 其中isBaseType中,!!两个逻辑非最后是将传入的参数转为boolean
  • isObjectType用来判断是否为对象
  • isNullValue用来判断是否为空一个空对象
    for (const key in obj) {
        const para = obj[key]
        if (isBaseType(para) && !(isObjectType(para))) {        //(1)
            result.push(true)
        } 
        if(!isBaseType(para)){          //(2)
            result.push(false)
        } 
        if (isObjectType(para) && !(isNullValue(para))) {   //(3)
            result.push(false)
        } 
        if(isObjectType(para) && isNullValue(para)){        //(4)
            result.push(toArray(para))
        }
    }
  • 这里的for...in用来遍历传入的对象, obj[key]表示对象属性的值
  • 第一个if也就是(1)的判断条件是当前的para是一个有值的基础值,比如obj.key7
  • 后面还同时调用了!isObjectType(para)来要求不能是一个对象,这样做是为了避免如obj.key4这样的值转为true
  • 第二个if就很简单了,只要是一个空的非对象就可以
  • 下面是第三个if,它的要求是必须为一个对象同时为空
  • 最后一个if要求obj[key]是一个对象,同时不为空,这样就进入了递归调用
  • 现在让我们回过头来看一下,toArray的第一个if
if (!isNullValue(obj)) {
	result.push(false)
	return result
}
  • 比如当前递归传入的值为obj.key13,[{}]数组内包含了一个空对象
  • 在递归中,当前我们得到的toArray的形参obj就是obj.key13这个数组内的空对象
  • isNullValue中返回的结果为true,对他取反,push进当前递归深度的result中并返回给上层,递归调用结束
return result
  • 然后就是函数最后的一段,将保存了结果的result返回出去

结语

此文章已收录至《JavaScript每日一题》专栏,如果你对本专栏有任何建议,欢迎反馈。如果你对此文章中的题目还有不懂的地方,那么请在评论区留言与大家一起讨论吧。 创作不易,少年,就请留个赞再走吧!