我有一个具有嵌套属性的对象,其中一些有一个'选择'属性。我试图使用下划线获取这些值,即使我成功了代码看起来不是很可读:
_.chain(config)
.pairs()
.map(function(e) {
var s = {};
s[e[0]] = _.chain(e[1])
.filter(function(e) {
if (e.selected) {
return e;
}
})
.pluck('name')
.join(',')
.value();
return s;
})
.flatten()
.filter(function(e) {
if (_.values(e)[0] !== '') {
return e;
}
})
.reduce(_.extend)
.value();
这是我使用的配置对象:
var config = {
'property__1': [
{name: 'test1', selected: 1},
{name: 'test2'}
],
'property__2': [
{name: '0'},
{name: '1', selected: 1},
{name: '2'},
{name: '3'},
{name: '4', selected: 1}
],
'property__3': [
{name: '0'},
{name: '1'},
{name: '2', selected: 1},
{name: '3'}
],
'property__4': [
{name: 'test1'},
{name: 'test2', selected: 1}
]
};
并希望获得以下输出:
{
"property__1": "test1",
"property__2": "1,4",
"property__3": "2",
"property__4": "test2"
}
还有什么我可以做的重构它,或者我不知道的任何可能有助于使这段代码更具可读性的属性吗?
答案 0 :(得分:2)
有些观点:
filter
回调应该返回一个布尔值,而不是应该收集的对象。它只是return e.selected == 1
,甚至只是返回1
与undefined
。.flatten()
_.values(e)[0]
看起来特别糟糕。您应该考虑在制作对象之前过滤。我和
一起去_.reduce(config, function(s, e, k) {
var vals = _.filter(e, _.property("selected"));
if (vals.length)
s[k] = _.pluck(vals, "name").join();
return s;
}, {});
不可否认,.length
的测试与空.name
的字符串检查不同,但我想这是你真正想要的
当然,你可以将其延伸到
_.chain(config)
.pairs()
.map(function(p) {
return [p[0], _.filter(p[1], _.property("selected"))];
}).filter(function(p) {
return p[1].length;
}).map(function(p) {
return [p[0], _.chain(p[1]).pluck("name").join().value()];
})
.object()
.value();
...这更像是你原来的那个,但只看起来很长而不是更好。
答案 1 :(得分:0)
我是使用jQuery每个循环完成的。代码更简单易读。
var output = {}
//first each loop will iterate over property__1,property__2,...
$.each(config, function(propertyName) {
//here 'this' will refer to the array that 'property__1' holds,
//and the next each loop will iterate over this array.
$.each(this, function(){
//here 'this' will refer to the element of the array,
//for example object {name: 'test1', selected: 1}
if(typeof this.selected !== 'undefined'){ //check if 'selected' property is present
//if present then map required value on propertyName
if(output[propertyName]){
output[propertyName] += ',' + this.name; //append comma seperated if already mapped
} else {
output[propertyName] = this.name; //map directly if for the first time
}
}
});
});
console.log(output);
让我知道这有助于你:)