JavaScript数组 - 有效地计算给定间隔的平均值

时间:2016-08-04 18:43:33

标签: javascript arrays algorithm average

我有两个数组,其中一个表示数据,另一个表示间隔。两者都是排序的,它们的起始值和结束值匹配。我通过嵌套for循环来计算给定间隔中数据点的平均值。结果,我最终得到每个间隔的一个数据值。对于较小尺寸的阵列,< 100-500长度,这些线性循环完成工作,然而,这种方法成为几千个数据点的问题。任何建议将不胜感激。

请参阅下面的简化代码,最后附上JSfiddle的链接

var TimelineArray = [0, 10, 20, 30, 40, 40, 60, 70, 80, 90, 100],
	DataArray = [0, 2, 4, 5, 8, 11, 19, 22, 24, 25, 30, 31, 38, 39, 51, 56, 57, 58, 59, 64, 74, 76, 89, 91, 92, 94, 98, 100],
	DataArrayA = [];

for (i = 0; i < TimelineArray.length-1; i++) {
	var dataPointsInGivenTimeInterval = [];
	for (j = 0; j < DataArray.length; j++) {
		if (DataArray[j] > TimelineArray[i] && DataArray[j] <= TimelineArray[i+1]) {
			dataPointsInGivenTimeInterval.push(DataArray[j]);
		}
	};
	if (dataPointsInGivenTimeInterval.length == 0) {
		DataArrayA.push(null);
	}
	else {
		var sumOfdataPoints = null;
		for (k = 0; k < dataPointsInGivenTimeInterval.length; k++) {
			sumOfdataPoints += dataPointsInGivenTimeInterval[k];
		}
		var avg = sumOfdataPoints / dataPointsInGivenTimeInterval.length;
		DataArrayA.push(avg);
	}
} // end for

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

控制台输出

[0, 10, 20, 30, 40, 40, 60, 70, 80, 90, 100]
[4.75, 15, 25.25, 36, null, 56.2, 64, 75, 89, 95]

以下是JSfiddle的代码 - calculating average values for given intervals

3 个答案:

答案 0 :(得分:2)

由于数组已排序,您可以根据时间轴和数据的大小进行线性处理:

&#13;
&#13;
var timeline = [0, 10, 20, 30, 40, 40, 60, 70, 80, 90, 100],
    data = [0, 2, 4, 5, 8, 11, 19, 22, 24, 25, 30, 31, 38, 39, 51, 56, 57, 58, 59, 64, 74, 76, 89, 91, 92, 94, 98, 100];
var averages = new Array(timeline.length - 1);
for (var i = 0, j = 0; i < timeline.length; i++) {
  var sum = 0,
      items = 0;
  for (; data[j] <= timeline[i]; j++) {
    sum += data[j];
    ++items;
  }
  if(i) averages[i-1] = sum / items;
}
console.log(averages);
&#13;
.as-console-wrapper {
  max-height: 100% !important;
  top: 0;
}
&#13;
&#13;
&#13;

答案 1 :(得分:1)

您不需要在每次迭代时从头开始重新扫描DataArray

&#13;
&#13;
var TimelineArray = [0, 10, 20, 30, 40, 40, 60, 70, 80, 90, 100];
var DataArray = [0, 2, 4, 5, 8, 11, 19, 22, 24, 25, 30, 31, 38, 39, 51, 56, 57, 58, 59, 64, 74, 76, 89, 91, 92, 94, 98, 100];

var res = [], pos = 0;

TimelineArray.forEach(function(v, i) {
  for(var sum = 0, n = 0; DataArray[pos] <= v; n++) {
    sum += DataArray[pos++];
  }
  i && res.push(n ? sum / n : null);
});

console.log(res);
&#13;
&#13;
&#13;

答案 2 :(得分:0)

不确定它是否会更快,但这是以不同的方式解决它:

var TimelineArray = [0, 10, 20, 30, 40, 40, 60, 70, 80, 90, 100],
DataArray = [0, 2, 4, 5, 8, 11, 19, 22, 24, 25, 30, 31, 38, 39, 51, 56, 57, 58, 59, 64, 74, 76, 89, 91, 92, 94, 98, 100],
DataArrayA = [];
  
function avg(arr){
  if(arr!= null && arr.length > 0)
    return arr.reduce(function(a, b){ return a+b;}, 0) / arr.length;
  return null;
}
for(var i = 0; i < TimelineArray.length-1; i++){
  var interval = [TimelineArray[i], TimelineArray[i+1]];
  var data = DataArray.filter(function(a){ return a > interval[0] && a <= interval[1]});
  DataArrayA.push(avg(data));
}

console.log(DataArrayA);

编辑1:删除了一个循环。