Skip to main content

模拟lodash中的_.get()函数

tip

考察编码能力

一、题意

补充函数的 TODO 部分,模拟 lodash 中的 _.get() 函数。

function get(object, ...path){
// TODO
}

测试用例

// 输入:
const obj = {
selector: { to: { toutiao: "FE Coder" } },
target: [1, 2, { name: "byted" }],
};

get(obj, "selector.to.toutiao", "target[0]", "target[2].name");

// 输出:
// ['FE coder', 1, 'byted']

二、背景知识

loadsh的_.get()定义

_.get(object, path, [defaultValue])
根据 object对象的path路径获取值。
如果解析 value 是 undefined 会以 defaultValue 取代。

参数

object (Object): 要检索的对象。
path (Array|string): 要获取属性的路径。
[defaultValue] (*): 如果解析值是 undefined ,这值会被返回。

返回

(*): 返回解析的值。

例子

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

_.get(object, 'a[0].b.c');
// => 3

_.get(object, ['a', '0', 'b', 'c']);
// => 3

_.get(object, 'a.b.c', 'default');
// => 'default'

lodash部分源码

function baseGet(object, path) {
path = castPath(path, object)

let index = 0
const length = path.length

while (object != null && index < length) {
object = object[toKey(path[index++])]
}
return (index && index == length) ? object : undefined
}

function get(object, path, defaultValue) {
const result = object == null ? undefined : baseGet(object, path)
return result === undefined ? defaultValue : result
}

export default get

三、解法

function get(object, ...path){
// 如果object是null,则直接返回undefined即可
if(object == null){
return undefined;
}

// 对path逐个处理,并依靠map方法,返回处理结果
return path.map(item => {
// 第1步,先处理下标`[*]`情况,并转换为数组
// a[3].b.c => a.3.b.c => [a, 3, b, c]
const keys = item.replace(/\[(\d+)\]/g, ".$1")
.split(".");

let result = object;
let index = 0;
const length = keys.length;

// 逐级获取object的下标结果
while(result !== null && index < length && typeof result !== 'undefined'){
result = result[keys[index++]];
}

// 最终返回结果,只有遍历完keys,才返回result,否则,视为中途出错,返回undefined
return (index && index == length) ? result : undefined;
})
}