题目描述:
给定一个源对象和一个包含键值对的目标对象, 找到目标对象中的键与值在源对象中的键值路径.
举个栗子:
const obj = {
a: { b: 1, c: 2 },
d: {
e: 3,
f: {
g: 4,
h: 5,
l: 7
},
},
i: {
j: 6,
k: {
l: 7,
m: 8,
},
},
};
{value:7, key:'l'} ===> [['d', 'f', 'l'], ['i', 'k', 'l']]
{value:7, key:'m'} ===> []
{valueu:2, key:'c'} ===> [['a', 'c']]
大致思路:
遍历源对象键值, 若该键值对应的值为数值, 则比较该键值与目标键值是否相匹配, 匹配则将该键push进数组, 若为对象, 则进行递归操作。
代码如下:
function getObjPath(obj: { [key in string]: any }, keyValue: { key: string, value: number }): string[][] {
/定义返回值
const result: string[][] = [];
//递归函数
const fn = (o: { [key in string]: any }, count: number = 0) => {
const res = Object.keys(o).reduce((acc, cur) => {
const val = o[cur];
if (typeof val !== 'number') {
//当前值为一个对象, 进行递归操作
const arr = fn(val, count + 1);
//判断函数是否为null, 为null则说明没匹配上
if (arr) {
//匹配上了, 将当前键与返回值组合, 生成path
acc = [cur, ...arr];
//判断当前执行环境是否为最外层, 是则将path push进最后的返回值中
count === 0 && result.push(acc);
}
} else if (keyValue.key === cur && keyValue.value === val) {
//匹配上了,将键值push进数组
acc.push(cur);
}
return acc;
}, [] as string[]);
return res.length ? res : null;
};
fn(obj);
return result;
}