Javascript 使用下划线查询对象

Javascript 使用下划线查询对象,javascript,underscore.js,Javascript,Underscore.js,我有一个具有嵌套属性的对象,其中一些具有“selected”属性。我尝试使用下划线获取这些值,尽管我成功了,但代码看起来不太可读: _.chain(config) .pairs() .map(function(e) { var s = {}; s[e[0]] = _.chain(e[1]) .filter(function(e) { if (e.selected) { return e; } }

我有一个具有嵌套属性的对象,其中一些具有“selected”属性。我尝试使用下划线获取这些值,尽管我成功了,但代码看起来不太可读:

_.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"
}
我还可以做些什么来重构它,或者我不知道哪些属性可能有助于提高这段代码的可读性?

以下几点:

  • 过滤器
    回调应该返回布尔值,而不是应该收集的对象。它只返回e.selected==1,或者甚至只返回
    1
    vs
    未定义的
  • 我不确定
    .flatte()
    需要什么
  • \u.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();

…这更像是您原来的一个,但它看起来很长而不是更好。

我使用jQuery each循环实现了这一点。代码更加简单易读

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);

让我知道这有助于您:)

为什么要使用jQuery而不是普通循环?顺便说一句,命令式风格可能更“可读”(更长),但通常不被认为更简单。