2016-11-27 59 views
0
总和

我需要为每个班次总结键值(K1,K2,K3 ...)机(M1,M2,M3 ...)(S1,S2,S3 ),并创建一个新的对象(考虑波纹管)如何重组对象,并找到UnderscoreJS

我失去了耐心jquery $.eachforEach方法(因为我需要处理的5级对象)和跨UnderscoreJS来了。

我知道我应该为对象http://underscorejs.org/#objects使用函数的多种组合,但由于我是一个纯粹的前端人员,对查询和db知之甚少,所以找不到正确的方法来做到这一点。

鉴于JSON结构:

var data = { 
    "28-11":{ 
     "S1":{ 
      "M1":{ 
       "K1": 10, 
       "K2": 12, 
       "K3": 15 
      }, 
      "M2":{ 
       "K1": 8, 
       "K2": 6, 
       "K3": 5 
      } 
     }, 
     "S2":{ 
      "M1":{ 
       "K1": 8, 
       "K2": 6, 
       "K3": 5 
      }, 
      "M2":{ 
       "K1": 10, 
       "K2": 12, 
       "K3": 15 
      } 
     } 
    } 
} 

我需要获取以下信息:

var allShiftsData = { 
    "28-11":{ 
    "M1":{ 
     "K1": 18, 
     "K2": 18, 
     "K3": 20 
    }, 
    "M2":{ 
     "K1": 18, 
     "K2": 18, 
     "K3": 20 
    } 
    } 
} 

回答

1

一种方法是在每个对象的属性一个4级的迭代,总结机器进入的结果,因为我们遇到他们:

const data = {"28-11":{"S1":{"M1":{"K1":10,"K2":12,"K3":15},"M2":{"K1":8,"K2":6,"K3":5}},"S2":{"M1":{"K1":8,"K2":6,"K3":5},"M2":{"K1":10,"K2":12,"K3":15}}}}; 
 

 
const { 
 
    keys 
 
} = Object; 
 

 
const each = (obj, cb) => { 
 
    for (const prop of keys(obj)) { 
 
    cb(obj[prop], prop); 
 
    } 
 
}; 
 

 
const sumShiftsPerDate = (data) => { 
 
    const result = {}; 
 
    
 
    each(data, (shifts, date) => { 
 
    result[date] = {}; 
 

 
    each(shifts, (machines, shift) => { 
 
     each(machines, (machineKeys, machine) => { 
 
     result[date][machine] = result[date][machine] || {}; 
 

 
     each(machineKeys, (keyValue, keyName) => { 
 
      result[date][machine][keyName] = 
 
      (result[date][machine][keyName] || 0) + keyValue; 
 
     }); 
 
     }); 
 
    }); 
 
    }); 
 

 
    return result; 
 
}; 
 

 
console.log(sumShiftsPerDate(data));

还是使用下划线等价的each

const data = {"28-11":{"S1":{"M1":{"K1":10,"K2":12,"K3":15},"M2":{"K1":8,"K2":6,"K3":5}},"S2":{"M1":{"K1":8,"K2":6,"K3":5},"M2":{"K1":10,"K2":12,"K3":15}}}}; 
 

 
const sumShiftsPerDate = (data) => { 
 
    const result = {}; 
 
    
 
    _.each(data, (shifts, date) => { 
 
    result[date] = {}; 
 

 
    _.each(shifts, (machines, shift) => { 
 
     _.each(machines, (machineKeys, machine) => { 
 
     result[date][machine] = result[date][machine] || {}; 
 

 
     _.each(machineKeys, (keyValue, keyName) => { 
 
      result[date][machine][keyName] = 
 
      (result[date][machine][keyName] || 0) + keyValue; 
 
     }); 
 
     }); 
 
    }); 
 
    }); 
 

 
    return result; 
 
}; 
 

 
console.log(sumShiftsPerDate(data));
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

甲多个功能的方法可以是使用对象映射到每个日期对象从一个移位容器转换成在移位一个机容器中,并使用减少将它们转换成的总和机器关键值。

const data = {"28-11":{"S1":{"M1":{"K1":10,"K2":12,"K3":15},"M2":{"K1":8,"K2":6,"K3":5}},"S2":{"M1":{"K1":8,"K2":6,"K3":5},"M2":{"K1":10,"K2":12,"K3":15}}}}; 
 

 
const { 
 
    assign, keys 
 
} = Object; 
 

 
const reduceObject = (obj, cb, initial) => keys(obj). 
 
    reduce((acc, prop) => cb(acc, obj[prop], prop), initial); 
 

 
const mapObject = (obj, cb) => reduceObject(obj, (result, val, prop) => 
 
    assign(result, { 
 
    [prop]: cb(val, prop) 
 
    }), {}); 
 

 
const sumObjects = (first, second = {}) => 
 
    reduceObject(first, (result, val, prop) => 
 
    assign(result, { 
 
     [prop]: (val || 0) + (second[prop] || 0) 
 
    }), {} 
 
); 
 

 
const sumShiftsPerDate = (data) => 
 
    mapObject(data, (shifts, date) => 
 
    reduceObject(shifts, (result, shift) => 
 
     reduceObject(shift, (result, machineKeys, machineName) => 
 
     assign(result, { 
 
      [machineName]: sumObjects(machineKeys, result[machineName]) 
 
     }), 
 
     result 
 
    ), 
 
     {} 
 
    ) 
 
); 
 

 
console.log(sumShiftsPerDate(data));

下面是使用下划线的keysextendobjectdefaultsmapObjectreduce,而不是Object.keysObject.assignES6+ default parametersES6+ dynamic keys和自定义功能​​和reduceObject相同的方法:

const data = {"28-11":{"S1":{"M1":{"K1":10,"K2":12,"K3":15},"M2":{"K1":8,"K2":6,"K3":5}},"S2":{"M1":{"K1":8,"K2":6,"K3":5},"M2":{"K1":10,"K2":12,"K3":15}}}}; 
 

 
// throw in a mixin just for fun :) 
 
// http://underscorejs.org/#mixin 
 
_.mixin({ 
 
    sumObjects: (first, second) => 
 
    _.reduce(first, (result, val, prop) => 
 
     _.extend(result, _.object(
 
     [prop], [(val || 0) + (second[prop] || 0)] 
 
    )), {} 
 
    ) 
 
}); 
 

 
const sumShiftsPerDate = (data) => 
 
    _.mapObject(data, (shifts) => 
 
    _.reduce(shifts, (result, machines) => 
 
     _.reduce(machines, (result, machineKeys, machineName) => 
 
     _.extend(result, _.object(
 
      [machineName], [_.sumObjects(
 
      machineKeys, 
 
      _.defaults({}, result[machineName]))] 
 
     )), 
 
     result 
 
    ), 
 
     {} 
 
    ) 
 
); 
 

 
console.log(sumShiftsPerDate(data));
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

注:纯JS溶液具有在下划线溶液两个优点:

  1. 它使用本地方法其通常是更快和更稳定
  2. 它不会加载整个库只是为新人方法需要
0

你可以使用Object.keys和Array.forEach达到你所需要的。要解决这个

var data = { 
 
    "28-11": { 
 
    "S1": { 
 
     "M1": { 
 
     "K1": 10, 
 
     "K2": 12, 
 
     "K3": 15 
 
     }, 
 
     "M2": { 
 
     "K1": 8, 
 
     "K2": 6, 
 
     "K3": 5 
 
     } 
 
    }, 
 
    "S2": { 
 
     "M1": { 
 
     "K1": 8, 
 
     "K2": 6, 
 
     "K3": 5 
 
     }, 
 
     "M2": { 
 
     "K1": 10, 
 
     "K2": 12, 
 
     "K3": 15 
 
     } 
 
    } 
 
    } 
 
}; 
 

 
var output = {}; 
 

 
//Iterate over Dates 
 
Object.keys(data).forEach((date) => { 
 
    var dateObj = data[date]; 
 
    output[date] = {}; 
 

 
    //Iterate over Shifts 
 
    Object.keys(dateObj).forEach((shift) => { 
 
    var shiftObj = dateObj[shift]; 
 

 
    //Iterate over machines 
 
    Object.keys(shiftObj).forEach((machine) => { 
 
     //Initialize if the machine is not already iterated earlier. 
 
     output[date][machine] = output[date][machine] || {}; 
 
     Object.keys(shiftObj[machine]).forEach((keyValue) => { 
 

 
     if (!output[date][machine][keyValue]) { 
 
      output[date][machine][keyValue] = 0; 
 
     } 
 

 
     output[date][machine][keyValue] += shiftObj[machine][keyValue]; 
 

 
     }); 
 
    }); 
 
    }); 
 
}); 
 

 

 
console.log(output);

0

这里是我的版本:

const data = {"28-11":{"S1":{"M1":{"K1":10,"K2":12,"K3":15},"M2":{"K1":8,"K2":6,"K3":5}},"S2":{"M1":{"K1":8,"K2":6,"K3":5},"M2":{"K1":10,"K2":12,"K3":15}}}}; 

var out = {}; 

Object.keys(data).forEach(date => 
    Object.keys(data[date]).forEach(shift => 
     Object.keys(data[date][shift]).forEach(machine => 
      Object.keys(data[date][shift][machine]).forEach(key => { 
       if (out[date] === undefined) out[date] = {}; 
       if (out[date][machine] === undefined) out[date][machine] = {}; 
       if (out[date][machine][key] === undefined) out[date][machine][key] = 0; 
       out[date][machine][key] += data[date][shift][machine][key]; 

      }) 
     ) 
    ) 
) 
console.log(out) 
return out; 
0

这是另一种可能性。

var data = {"28-11":{"S1":{"M1":{"K1":10,"K2":12,"K3":15},"M2":{"K1":8,"K2":6,"K3":5}},"S2":{"M1":{"K1":8,"K2":6,"K3":5},"M2":{"K1":10,"K2":12,"K3":15}}}}; 
 
    
 
    data = _.mapObject(data, function (days) { 
 
     return _.map(days, function (day) { 
 
     return _.reduce(day, function (acc, machine) { 
 
      return _.extend({}, acc, _.mapObject(machine, function (keyVal, keyKey) { 
 
      return (acc[keyKey] || 0) + keyVal; 
 
      })); 
 
     }, {}); 
 
     }); 
 
    }); 
 
    
 
    console.log(data);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

Here's的JSBin。

老实说,如果你想得到好的地图和减少,我建议你通过this教程网页RxJS。你可以在开始使用RxJS时立即退出,但它会教你如何开始使用函数式编程,并教你如何映射过滤器并像老板一样减少。