想象一下有一个对象,我们正在尝试编写一个函数,该函数将'path'用作余量并打印其中的任何内容。如果输入无效,则引发错误。对象大小可能很大。
const obj = {
test: {
demo: [{
lname: 'dave'
}]
}
};
function getData(obj, dest) {
const path = dest.split('.');
return helper(obj, path);
function helper(obj, path) {
if (!path.length) return obj;
const cur = path.shift();
if ((Array.isArray(obj) && typeof obj === 'string') ||
(typeof obj === 'undefined')) {
throw new Error("Something wrong")
}
obj = obj[cur];
return helper(obj, path);
}
}
console.log(getData(obj, 'test.demo.0.lname'));
//console.log(getData(obj, 'test.demo.dave.lname')); // throws an error since in demo array you can't access 'dave'
我正在尝试找出编写此方法的较短方法是什么?我听说有人说我们可以写几行。
答案 0 :(得分:1)
一个简单快捷的实现可以使用Array#reduce来迭代地从对象上取下键,如下所示:
const obj = {
test: {
demo: [{
lname: 'dave'
}]
}
};
function getData(obj, dest) {
var keys = dest.split(".");
return keys.reduce(function(currentObject, key) {
if(typeof currentObject == "undefined") throw Error("Something wrong");
return currentObject[key];
}, obj)
}
console.log(getData(obj, 'test.demo.0.lname'));
console.log(getData(obj, 'test.demo.dave.lname')); // throws an error since in demo array you can't access 'dave'
这是更冗长的选项,为了演示正在发生的事情,您可以进一步缩短它
const obj = {
test: {
demo: [{
lname: 'dave'
}]
}
};
function getData(obj, dest) {
return dest.split(".").reduce((curr, key) => curr[key], obj)
}
console.log(getData(obj, 'test.demo.0.lname'));
console.log(getData(obj, 'test.demo.dave.lname')); // throws an error since in demo array you can't access 'dave'
您还可以避免引发错误,但是如果找不到密钥,只需返回undefined
const obj = {
test: {
demo: [{
lname: 'dave'
}]
}
};
function getData(obj, dest) {
return dest.split(".").reduce((curr, key) => curr != undefined ? curr[key] : undefined, obj)
}
console.log(getData(obj, 'test.demo.0.lname'));
console.log(getData(obj, 'test.demo.dave.lname')); // undefined
但是,尽管这很容易实现,但要以错误检查为代价。调试到底出了什么问题可能会很烦人,因为您必须知道数据对象和目标输入是什么,然后尝试找出手动缺少的键。因此,如果您想要更健壮和灵活的代码,则更长的实现通常会更好。
如果您使用的是Lodash,则可以使用其_.get,它更加健壮并可以处理更多语法
const obj = {
test: {
demo: [{
lname: 'dave'
}]
}
};
console.log(_.get(obj, 'test.demo.0.lname'));
console.log(_.get(obj, 'test.demo[0].lname'));
console.log(_.get(obj, ['test', 'demo', 0, 'lname']));
console.log(_.get(obj, 'test.demo.dave.lname')); // undefined
console.log(_.get(obj, 'test.demo.dave.lname', 'this is not dave but the default vale'));
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>