2015-12-17 82 views
3

我有以下数据结构,需要获取竞争者对象中各项的每个列的平均值。然后我需要把它变成一个数组数组。第一个值需要是列的平均值(四舍五入),第二个值需要是从0开始递增的值。对数组对象进行迭代并计算平均值

output = [[6, 0], [4, 1], [3, 2], [3, 3], [6, 4]]; 

结构示例:

input = { 
    categories: [ 
    "Cat 1", 
    "Cat 2", 
    "Cat 3", 
    "Cat 4", 
    "Cat 5" 
    ], 
    contenders: { 
    item1:  [5, 3, 4, 4, 6], 
    item2:  [6, 10, 4, 4, 6], 
    item3:  [6, 3, 4, 9, 6], 
    item4:  [8, 3, 5, 4, 6], 
    item5:  [9, 3, 4, 4, 6], 
    item6:  [10, 2, 7, 4, 6], 
    item7:  [4, 3, 4, 4, 6], 
    item8:  [1, 5, 4, 4, 6] 
    }, 
    misc: [0, 3, 4, 4, 6] 
}; 

我已经创建了一个可以为我做的平均值的函数:

function getAvg(data) { 
    return data.reduce(function (p, c) { 
       return p + c; 
      })/data.length; 
} 

但不能完全解决如何在迭代项目的值来获得我的结果。

+1

为什么你有8个竞争者,只有5个元素在输出数组?这是令人困惑的 – gurvinder372

+1

我想他想要的是平均列,而不是每一行(关键)。所以所有的答案都被误解了 – juvian

+0

这是因为输出数组需要与类别匹配。 – user1513388

回答

0

您可以使用Object.keys,为获取属性,然后与Array.prototype.forEach交换数值。

var input = { categories: ["Cat 1", "Cat 2", "Cat 3", "Cat 4", "Cat 5"], contenders: { item1: [5, 3, 4, 4, 6], item2: [6, 10, 4, 4, 6], item3: [6, 3, 4, 9, 6], item4: [8, 3, 5, 4, 6], item5: [9, 3, 4, 4, 6], item6: [10, 2, 7, 4, 6], item7: [4, 3, 4, 4, 6], item8: [1, 5, 4, 4, 6] }, misc: [0, 3, 4, 4, 6] }, 
 
    output = [], 
 
    sum = [], count = []; 
 

 
Object.keys(input.contenders).forEach(function (k) { 
 
    input.contenders[k].forEach(function (a, i) { 
 
     sum[i] = (sum[i] || 0) + a; 
 
     count[i] = (count[i] || 0) + 1; 
 
    }); 
 
}); 
 
output = sum.map(function (a, i) { 
 
    return [Math.round(sum[i]/count[i]), i] 
 
}); 
 

 
document.write('<pre>' + JSON.stringify(output, 0, 4) + '</pre>');

+0

完美无瑕。非常感谢。 – user1513388

+0

另一个问题,如果你不介意。 'misc'数组的内容已经被平均。我只需要将它看起来像这样:'output2 = [[9,0],[9,1],[9,2],[9,3],[4,4]]与' output'。什么是最好的方法来做到这一点? – user1513388

+0

@ user1513388,'var output2 = input.misc.map(function(a,i){return [a,i];});'应该这样做。 –

1

你可以使用的Object.keys组合来获得每个项目在contenders,然后用map创建从结果一个新的数组:

function getAvg(data) { 
 
    return data.reduce(function (p, c) { 
 
    return p + c; 
 
    })/data.length; 
 
} 
 
var input = { 
 
    categories: [ 
 
    "Cat 1", 
 
    "Cat 2", 
 
    "Cat 3", 
 
    "Cat 4", 
 
    "Cat 5" 
 
    ], 
 
    contenders: { 
 
    item1:  [5, 3, 4, 4, 6], 
 
    item2:  [6, 10, 4, 4, 6], 
 
    item3:  [6, 3, 4, 9, 6], 
 
    item4:  [8, 3, 5, 4, 6], 
 
    item5:  [9, 3, 4, 4, 6], 
 
    item6:  [10, 2, 7, 4, 6], 
 
    item7:  [4, 3, 4, 4, 6], 
 
    item8:  [1, 5, 4, 4, 6] 
 
    }, 
 
    misc: [0, 3, 4, 4, 6] 
 
}; 
 
console.log(Object.keys(input.contenders).map(function(key, index) { 
 
    return [getAvg(input.contenders[key]), index]; 
 
}));

2

如果我理解正确的,你想每一列,这意味着每一个第一个元素在你的项目键作为举例而言,所有阵列的平均值,那么你就需要做一个每列的数组使用您的平均功能。然而,这样做你已经可以计算出平均值,这里是一个办法:

 var input = { categories: ["Cat 1", "Cat 2", "Cat 3", "Cat 4", "Cat 5"], contenders: { item1: [5, 3, 4, 4, 6], item2: [6, 10, 4, 4, 6], item3: [6, 3, 4, 9, 6], item4: [8, 3, 5, 4, 6], item5: [9, 3, 4, 4, 6], item6: [10, 2, 7, 4, 6], item7: [4, 3, 4, 4, 6], item8: [1, 5, 4, 4, 6] }, misc: [0, 3, 4, 4, 6] } 
 

 

 
    var output = [] 
 

 
    var cols = input.contenders.item1.length // amount of columns (I assume all items have same amount of columns) 
 

 
    for(var i=0;i<cols;i++){ 
 
     output[i] = [0,i] // start output with sum of 0 and index i 
 
    } 
 

 
    for(var key in input.contenders){ 
 
     var arr = input.contenders[key] 
 
     for(var k = 0;k<cols;k++){ 
 
     output[k][0]+=arr[k] // add the value of the array in the kth position to the kth output sum 
 
     } 
 
    } 
 

 
    for(var i=0;i<cols;i++){ 
 
     output[i][0] = Math.round(output[i][0]/Object.keys(input.contenders).length) // now just divide by the amount of keys 
 
    } 
 

 
    console.log(output)

0

你应该完全符合Object.keys走在其他的答案建议。然而,完整性或较少的情况下的兼容性让你烦恼: 您可以建立一个字符串,它指你正在寻找的阵列,像这样

for (var i=1;i<9;i++) { doSomething(input.contenders["item"+i]); } 

这需要你知道多少的项目和他们的名字提前。