2017-01-12 6 views
2

Это оригинальный JSON данные:оптимизация кода Lodash/рефакторинга

var data= [ 
     { project: "ABC", area: 'Test',  subArea: 'Dev',  done: 10 }, 
     { project: "ABC", area: 'Test',  subArea: 'QA',  done: 10 }, 
     { project: "ABC", area: 'Test',  subArea: 'Support', done: 10 }, 
     { project: "ABC", area: 'External', subArea: 'Dev',  done: 5 }, 
     { project: "ABC", area: 'External', subArea: 'QA',  done: 5 }, 
     { project: "ABC", area: 'External', subArea: 'Support', done: 5 }, 
     { project: "ABC", area: 'Escalation', subArea: 'Dev',  done: 20 }, 
     { project: "ABC", area: 'Escalation', subArea: 'QA',  done: 20 }, 
     { project: "ABC", area: 'Escalation', subArea: 'Support', done: 20 }, 
     { project: "ABC123", area: 'Test',  subArea: 'Dev',  done: 20 }, 
     { project: "ABC123", area: 'Test',  subArea: 'QA',  done: 20 }, 
     { project: "ABC123", area: 'Test',  subArea: 'Support', done: 20 }, 
     { project: "ABC123", area: 'External', subArea: 'Dev',  done: 10 }, 
     { project: "ABC123", area: 'External', subArea: 'QA',  done: 10 }, 
     { project: "ABC123", area: 'External', subArea: 'Support', done: 10 }, 
     { project: "ABC123", area: 'Escalation', subArea: 'Dev',  done: 5 }, 
     { project: "ABC123", area: 'Escalation', subArea: 'QA',  done: 5 }, 
     { project: "ABC123", area: 'Escalation', subArea: 'Support', done: 5 }, 
    ]; 

Что мне нужно, чтобы сгруппировать элементы по проекта, разделить их в областях и просуммировать сделали часов для каждого подрайон. Новый результат JSON должен быть такой:

[ 
    { 
     "name": "ABC", 
     "test": { 
     "total": 30, 
     "totalDev": 10, 
     "totalQA": 10, 
     "totalSup": 10 
     }, 
     "external": { 
     "total": 15, 
     "totalDev": 5, 
     "totalQA": 5, 
     "totalSup": 5 
     }, 
     "escalation": { 
     "total": 60, 
     "totalDev": 20, 
     "totalQA": 20, 
     "totalSup": 20 
     } 
    }, 
    { 
     "name": "ABC123", 
     "test": { 
     "total": 60, 
     "totalDev": 20, 
     "totalQA": 20, 
     "totalSup": 20 
     }, 
     "external": { 
     "total": 30, 
     "totalDev": 10, 
     "totalQA": 10, 
     "totalSup": 10 
     }, 
     "escalation": { 
     "total": 15, 
     "totalDev": 5, 
     "totalQA": 5, 
     "totalSup": 5 
     } 
    } 
] 

С моим кодовым сильфоном Я уже получаю результат я хочу, но я думаю, что код может быть более оптимизирован. Без повторения и всех условных проверок без жесткого кода свойства области и подрайонов внутри блока карты, поскольку эти значения имеют динамическую область на стороне сервера.

var sum = (total, item) => total += item.done; 

result = _.chain(data) 
      .groupBy(function(value) { return value.project }) 
      .map((projectGroup, projectName) => ({ 
        name: projectName, 
        test: { 
         total: _.reduce(_.filter(projectGroup, (o) => (o.area === 'Test')) , sum, 0), 
         totalDev: _.reduce(_.filter(projectGroup, (o) => (o.area === 'Test' && o.subArea === 'Dev')) , sum, 0), 
         totalQA: _.reduce(_.filter(projectGroup, (o) => (o.area === 'Test' && o.subArea === 'QA')) , sum, 0), 
         totalSup: _.reduce(_.filter(projectGroup, (o) => (o.area === 'Test' && o.subArea === 'Support')) , sum, 0) 
        }, 
       external: { 
         total: _.reduce(_.filter(projectGroup, (o) => (o.area === 'External')) , sum, 0), 
         totalDev: _.reduce(_.filter(projectGroup, (o) => (o.area === 'External' && o.subArea === 'Dev')) , sum, 0), 
         totalQA: _.reduce(_.filter(projectGroup, (o) => (o.area === 'External' && o.subArea === 'QA')) , sum, 0), 
         totalSup: _.reduce(_.filter(projectGroup, (o) => (o.area === 'External' && o.subArea === 'Support')) , sum, 0) 
        }, 
        escalation: { 
         total: _.reduce(_.filter(projectGroup, (o) => (o.area === 'Escalation')) , sum, 0), 
         totalDev: _.reduce(_.filter(projectGroup, (o) => (o.area === 'Escalation' && o.subArea === 'Dev')) , sum, 0), 
         totalQA: _.reduce(_.filter(projectGroup, (o) => (o.area === 'Escalation' && o.subArea === 'QA')) , sum, 0), 
         totalSup: _.reduce(_.filter(projectGroup, (o) => (o.area === 'Escalation' && o.subArea === 'Support')) , sum, 0) 
        }  
    })) 
+0

'.groupBy (функция (значение) {возвращение value.project})' может быть просто '.groupBy ('Проект')' –

+0

почему тест аЬс totaldev = 30? откуда приходит этот номер? –

+1

Я отредактировал, теперь его правильно. – sandrojack

ответ

0

Не знаю, что вы хотите оптимизировать здесь, lodash должен сделать это вместо вас. У меня есть только одно замечание

var sum = (total, item) => total += item.done; 
function reduceData(projectGroup, projectName, comparationLabel) { 
    return { 
    total: _.reduce(_.filter(projectGroup, (o) => (o.area === comparationLabel)) , sum, 0), 
    totalDev: _.reduce(_.filter(projectGroup, (o) => (o.area === comparationLabel && o.subArea === 'Dev')) , sum, 0), 
    totalQA: _.reduce(_.filter(projectGroup, (o) => (o.area === comparationLabel && o.subArea === 'QA')) , sum, 0), 
    totalSup: _.reduce(_.filter(projectGroup, (o) => (o.area === comparationLabel && o.subArea === 'Support')) , sum, 0) 
    } 
} 
result = _.chain(data) 
      .groupBy(function(value) { return value.project }) 
      .map((projectGroup, projectName) => ({ 
        name: projectName, 
        test: reduceData(projectGroup, projectName, 'Test'), 
        external: reduceData(projectGroup, projectName, 'External'), 
        escalation: reduceData(projectGroup, projectName, 'Escalation')  
    })) 

И да, вы можете избежать от _.filter(projectGroup, (o), если вы будете делать какой-то кэш, но вы будете экономить небольшое количество программных ресурсов.

+0

Спасибо! вот что я искал! – sandrojack

0

Вместо вложенности, как это:

_.reduce(_.filter(projectGroup, ...), sum, 0) 

Вы можете сделать это, чтобы предотвратить перекручивание по коллекции дважды:

_(projectGroup).filter(...).reduce(sum, 0).value() 
+0

Спасибо! Я сделаю изменения. – sandrojack

0

Почему бы не использовать один цикл в простом Javascript для группирования и суммируя часы?

Это предложение использует хеш-таблицу и группы по значению project.

var data = [{ project: "ABC", area: 'Test', subArea: 'Dev', done: 10 }, { project: "ABC", area: 'Test', subArea: 'QA', done: 10 }, { project: "ABC", area: 'Test', subArea: 'Support', done: 10 }, { project: "ABC", area: 'External', subArea: 'Dev', done: 5 }, { project: "ABC", area: 'External', subArea: 'QA', done: 5 }, { project: "ABC", area: 'External', subArea: 'Support', done: 5 }, { project: "ABC", area: 'Escalation', subArea: 'Dev', done: 20 }, { project: "ABC", area: 'Escalation', subArea: 'QA', done: 20 }, { project: "ABC", area: 'Escalation', subArea: 'Support', done: 20 }, { project: "ABC123", area: 'Test', subArea: 'Dev', done: 20 }, { project: "ABC123", area: 'Test', subArea: 'QA', done: 20 }, { project: "ABC123", area: 'Test', subArea: 'Support', done: 20 }, { project: "ABC123", area: 'External', subArea: 'Dev', done: 10 }, { project: "ABC123", area: 'External', subArea: 'QA', done: 10 }, { project: "ABC123", area: 'External', subArea: 'Support', done: 10 }, { project: "ABC123", area: 'Escalation', subArea: 'Dev', done: 5 }, { project: "ABC123", area: 'Escalation', subArea: 'QA', done: 5 }, { project: "ABC123", area: 'Escalation', subArea: 'Support', done: 5 }], 
 
    result = []; 
 

 
data.forEach(function (a) { 
 
    var area = a.area.toLowerCase(), 
 
     subArea = 'total' + a.subArea; 
 

 
    if (!this[a.project]) { 
 
     this[a.project] = { name: a.project }; 
 
     result.push(this[a.project]); 
 
    } 
 
    this[a.project][area] = this[a.project][area] || { total: 0 }; 
 
    this[a.project][area][subArea] = (this[a.project][area][subArea] || 0) + a.done; 
 
    this[a.project][area].total += a.done; 
 
}, Object.create(null)); 
 

 
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

+0

Спасибо! Ваш код действительно хорош и решил мою проблему, но теперь я просто чувствую себя более комфортно, используя Lodash. – sandrojack

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