2014-10-15 5 views
0

У меня есть объект с вложенными атрибутами, а некоторые из них имеют свойство «selected». Im пытается получить эти значения с помощью подчеркивания, и хотя мне удалось код не смотрит очень читаемый:Запрос объекта с использованием подчеркивания

_.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" 
} 

есть ли что-нибудь еще, что я мог сделать, чтобы реорганизовать его, или какое-либо свойство, Im не знает о том, что может быть полезно, чтобы сделать этот кусок кода дополнительной readab le?

ответ

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

... который больше похож на ваш оригинал, но это выглядит просто не лучше.

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

Позвольте мне знать, что это поможет вам :)

+0

Почему бы использовать JQuery вместо обычного цикла? Btw, императивный стиль может быть более «читаемым» (более длинным), но обычно он не считается более простым. – Bergi

Смежные вопросы