簡體   English   中英

使用lodash動態計算嵌套集合的平均值

[英]Dynamically calculate the average for a nested collection using lodash

我有一個對象(集合)的JSON數組,如:

[{
  "x": {
        "x1": 1
  },
  "y": {
    "yt": 0,
    "zt": 4,
    "qa": 3,
    "ft": 0,
    ...
  }
},
{
  "x": {
        "x1": 5
  },
  "y": {
    "yt": 10,
    "zt": 2,
    "qa": 0,
    "ft": 0,
    ...
  }
}]

我想計算每個字段的平均值。 結果結構應該相同。 喜歡:

    {
      "x": {
            "x1": 3
      },
      "y": {
        "yt": 5,
        "zt": 3,
        "qa": 1.5,
        "ft": 0,
        ...
      }
    }

謝謝

您可以使用傳播語法和lodash的_.mergeWith()合並對象。 合並時,如果第二個參數(b)是一個數字,請將其除以原始數組中的項目數,即可得出其對總平均值的貢獻。 如果第一個參數(a)是數字,則將其相加而不除(以避免多次相加),如果未定義,則加0。

我添加了2個對象數組和3個對象數組的示例。

 const getAvg = (data) => _.mergeWith({}, ...data, (a, b) => { if(_.isNumber(b)) { return ((b || 0) / data.length) + (_.isNumber(a) ? (a || 0) : 0); } }); const data1 = [ {"x":{"x1":1},"y":{"yt":0,"zt":4,"qa":3,"ft":0}}, {"x":{"x1":5},"y":{"yt":10,"zt":2,"qa":0,"ft":0}} ]; const data2 = [ {"x":{"x1":1},"y":{"yt":0,"zt":4,"qa":3,"ft":0}}, {"x":{"x1":5},"y":{"yt":10,"zt":2,"qa":0,"ft":0}}, {"x":{"x1":3},"y":{"yt":2,"zt":6,"qa":3,"ft":0}} ]; const result1 = getAvg(data1); console.log('2 objects in the array: ', result1); const result2 = getAvg(data2); console.log('3 objects in the array: ', result2); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script> 

您可以首先收集和匯總同一數據結構中的所有值,然后通過除以給定數組的長度來計算平均值。

 function getParts(array, result) { function iter(o, r) { Object.keys(o).forEach(function (k) { if (o[k] && typeof o[k] === 'object') { return iter(o[k], r[k] = r[k] || {}); } r[k] = (r[k] || 0) + o[k]; }); } function avr(o) { Object.keys(o).forEach(function (k) { if (o[k] && typeof o[k] === 'object') { return avr(o[k]); } o[k] = o[k] /data.length; }); } data.forEach(function (a) { iter(a, result); }); avr(result); } var data = [{ x: { x1: 1 }, y: { yt: 0, zt: 4, qa: 3, ft: 0, } }, { x: { x1: 5 }, y: { yt: 10, zt: 2, qa: 0, ft: 0, } }], result = {}; getParts(data, result); console.log(result); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

 let objectArray = [{ "x": { "x1": 1 }, "y": { "yt": 0, "zt": 4, "qa": 3, "ft": 0, } }, { "x": { "x1": 5 }, "y": { "yt": 10, "zt": 2, "qa": 0, "ft": 0, } }]; function findAverage(array) { let counter = {}, result = {}, i, obj, key, subKey; // Iterate through array for (i = 0; i < array.length; i++) { obj = array[i]; // Copy each key in array element to counter object for (key in obj) { counter[key] = counter[key] || {}; // Increment and keep count of key-values of counter based on values in array element for (subKey in obj[key]) { counter[key][subKey] = counter[key][subKey] || {total: 0, numElements: 0}; counter[key][subKey].total += obj[key][subKey]; counter[key][subKey].numElements += 1; } } } // Go back through counter to find average of all existing subkeys (based on incremented total and the number of elements recorded) and throw it into result object for (key in counter) { result[key] = result[key] || {}; for (subKey in counter[key]) { result[key][subKey] = counter[key][subKey].total / counter[key][subKey].numElements; } } return result; } console.log(findAverage(objectArray)); 

並非將其設計為絕對最佳,並且可以在不事先知道對象結構的情況下遞歸地復制對象,但是我想使步驟盡可能地清晰。

編輯以允許作為摘要進行測試。 甚至不知道您可以在SO上做到這一點!

 var array = [{ "x": { "x1": 1 }, "y": { "yt": 0, "zt": 4, "qa": 3, "ft": 0 } }, { "x": { "x1": 5 }, "y": { "yt": 10, "zt": 2, "qa": 0, "ft": 0 } }]; function aintob(){ var o = {}; var first = array[0], second = array[1]; var result = {x:{},y:{}}; var each = function(letter, oa, ob){ var i, letter = {}; for(i in oa){ letter[i] = (oa[i]+ob[i])/2; } return letter; } ox = each("x", first.x, second.x); oy = each("y", first.y, second.y); return o; } console.log(aintob()); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM