这是我编写的一个回调(为了解决这个问题而稍微修改/简化),用于处理一些对象数据。
function (err, data) {
var rv;
if (data && data.result instanceof Array) {
rv = data.result.map(function (value) {
if (value && value.track_contributions instanceof Array) {
return value.track_contributions.map(function (innerValue) {
if (innerValue && innerValue.track) {
return innerValue.track.mid;
}
});
}
});
// flatten nested arrays
rv = [].concat.apply([], rv);
}
console.log(rv);
};
这是我正在处理的对象的样子:
{
"result": [
{
"type": "/music/artist",
"track_contributions": [
{
"track": {
"mid": "/m/015rm3l"
}
},
{
"track": {
"mid": "/m/0nm2km"
}
},
{
"track": {
"mid": "/m/010ksbq"
}
},
...
]
}
]
}
我希望回调的返回值如下所示:
[ '/m/015rm3l',
'/m/0nm2km',
'/m/010ksbq',
...
]
我的代码工作得很好,但我觉得所有的嵌套都是代码味道。
我应该如何使这种类型的代码更扁平、更具可读性和可维护性以及所有这些很棒的东西? promise ?一些 lodash 类型的实用程序?还有别的事吗?以上都是吗?
最佳答案
这是一个我认为更容易理解和维护的版本,没有重复的代码,因为它使用带有回调的通用遍历来添加数据结构的细节:
function process(err, data) {
var rv = [];
function doObject(obj, key, callback) {
if (obj[key] && obj[key] instanceof Array) {
obj[key].forEach(function(value) {
callback(value);
});
}
}
doObject(data, "result", function(result) {
doObject(result, "track_contributions", function(item) {
if (item.track && item.track.mid) {
rv.push(item.track.mid);
}
});
});
console.log(rv);
}
在不更改您正在使用的基本算法的情况下,您可以初始化 rv 并将结果直接推送到 rv 中,而不是创建随后必须展平的子数组。
function process(err, data) {
var rv = [];
if (data && data.result instanceof Array) {
data.result.forEach(function(value) {
if (value && value.track_contributions instanceof Array) {
value.track_contributions.forEach(function(innerValue) {
if (innerValue && innerValue.track) {
rv.push(innerValue.track.mid);
}
});
}
});
}
console.log(rv);
}
由于您在每个级别查找的属性名称都不同,因此使用递归来避免重复代码并不高效或容易(尽管这是一个选项)。
这是一个两级递归算法,尽管我认为增加的复杂性实际上并不值得。如果您的深度超过 2 个级别或任意数量的级别,则可能更有意义:
function process(err, data) {
var rv = [];
function doArray(item, key1, key2) {
if (item && item[key1] instanceofArray) {
item[key1].forEach(function(value) {
if (key2) {
doArray(value, key2);
} else if (value && value.track.mid) {
rv.push(value.track.mid);
}
});
}
}
doArray(data, "result", "track_contributions");
console.log(rv);
}
关于javascript - 展平嵌套回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27050901/