我有一个由两列表示为数组的“表”.第一列是1到20的数字,它们是标签,第二列是相应的值(秒):
my_array = [ [ 3,4,5,3,2 ],[ 12,14,16,11,12,10,20 ] ];
我需要每个标签的平均值(平均值):
my_mean_array = [ [ 2,5 ],[ 20/1,(12+11)/2,(14+12)/2,(16+10)/2 ] ]; // edit: The mean should be a float - the notion above is just for clarification. // Also the number 'labels' should remain as numbers/integers.
我的尝试:
var a = my_array[0]; var b = my_array[1]; m = []; n = []; for( var i = 0; a.length; i++){ m[ a[i] ] += b[i]; // accumulate the values in the corresponding place n[ a[i] ] += 1; // count the occurences } var o = []; var p = []; o = m / n; p.push(n); p.push(o);
解决方法
怎么样(原生JS,不会破坏旧版浏览器):
function arrayMean(ary) { var index = {},i,label,value,result = [[],[]]; for (i = 0; i < ary[0].length; i++) { label = ary[0][i]; value = ary[1][i]; if (!(label in index)) { index[label] = {sum: 0,occur: 0}; } index[label].sum += value; index[label].occur++; } for (i in index) { if (index.hasOwnProperty(i)) { result[0].push(parseInt(i,10)); result[1].push(index[i].occur > 0 ? index[i].sum / index[i].occur : 0); } } return result; }
FWIW,如果你想要花哨我已经创造了一些其他方法来做到这一点.它们依赖于外部库,并且很可能比原生解决方案慢一个数量级.但他们看起来更好.
看起来像这样,用underscore.js:
function arrayMeanUnderscore(ary) { return _.chain(ary[0]) .zip(ary[1]) .groupBy(function (item) { return item[0]; }) .reduce(function(memo,items) { var values = _.pluck(items,1),toSum = function (a,b) { return a + b; }; memo[0].push(items[0][0]); memo[1].push(_(values).reduce(toSum) / values.length); return memo; },[[],[]]) .value(); } // -------------------------------------------- arrayMeanUnderscore([[3,2],[12,20]]); // -> [[2,5],[20,11.5,13,13]]
或者像这样,真正伟大的linq.js(我用过v2.2):
function arrayMeanLinq(ary) { return Enumerable.From(ary[0]) .Zip(ary[1],"[$,$$]") .GroupBy("$[0]") .Aggregate([[],[]],function (result,item) { result[0].push(item.Key()); result[1].push(item.Average("$[1]")); return result; }); } // -------------------------------------------- arrayMeanLinq([[3,20]]); // -> [[3,[11.5,20]]
正如所怀疑的那样,“花哨”实现比本机实现慢一个数量级:jsperf comparison.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。