面试:实现 getValue 函数来获取path对应的值

1,152 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

前言

这是一个朋友在面试过程中遇到的一道题目,具体是哪家公司,这里就不在说了,今天就展开分析一下这个题目,希望可帮到看到这个题目的朋友。

题目

实现 getValue 函数来获取对象 path 对应的值。

var object = { 'a': [{ 'b': { 'c': 3 } }] };
var array = [{ "a": { b: [1] } }];

getValue(object, 'a[0].b.c') // 输出 3
getValue(array, '[0].a.b[0]') // 输出 z

题目分析

获取对象或者数组的值,是通过对应的 key 或者 [index]。如果拿到完整的 path 要获得对应的值,就需要先去分解 path,然后一层层的去取值。

如果没有找到对应的 path,则返回默认值

path 进行分解

path.split(".");

path 进行分类,可分为三种请情况

  1. 对象的 key: 'a'、'aaa'
  2. 数组的 index: '[0]' '[2]'
  3. 对象 key + indexaa:[0]

根据每一层的 path 获取对应的值

完整代码

function getValue(obj, path = "") {
    const paths = path.split(".");
    const attr = paths.shift();
    let result = "";


    // 正则表达式,用于匹配三种不同情况和分组取值
    // 'a'、'aaa'
    const reg1 = /^([a-zA-Z]+)$/;
    // '[0]' '[2]'
    const reg2 = /^(\[\d+\])$/;
    // aa:[0]
    const reg3 = /^([a-zA-Z]+)(\[\d+\])$/;
    
    // 根据每一层的 `path` 获取对应的值
    const _getValue = (paths, val) => {
        if (paths.length > 0 && (val !== null || val !== undefined)) {
            // 根据剩余的 path 继续执行查找
            result = getValue(val, paths.join("."));
        }
    };
    if (reg1.test(attr)) {
        // 获取第一层的值
        let val = obj[attr];
        result = val;
        // 继续执行深层次的查找
        _getValue(paths, val);
    } else if (reg2.test(attr)) {
        const index = attr.substr(1, attr.length - 2);
        let val = obj[index];
        result = val;
         // 继续执行深层次的查找
        _getValue(paths, val);
    } else if (reg3.test(attr)) {
        const { $1, $2 } = RegExp;
        let parentVal = obj[$1];
        const index = $2.substr(1, $2.length - 2);
        let val = parentVal[index];
        result = val;
         // 继续执行深层次的查找
        _getValue(paths, val);
    }

    return result;
};

console.log(getValue(object, 'a[0].b.c')) // 3
console.log(getValue(array, '[0].a.b[0]'))  // 1

附:

lodash.get

解题2

function getValue(obj, path) {
  const keys = path
    .replace(/\[(\d+)\]/g, '.$1') // 将 [index] 转换为 .index
    .split('.')
    .filter(Boolean); // 将路径字符串分割成键的数组

  console.log('keys: ', keys)
  let value = obj;

  for (const key of keys) {
    if (value && typeof value === 'object' && key in value) {
      value = value[key];
    } else {
      return undefined; // 如果未找到路径中的某个键,则返回 undefined
    }
  }

  return value;
}

结语

如果这篇文章帮到了你,欢迎点赞👍和关注⭐️。

文章如有错误之处,希望在评论区指正🙏🙏。