Как вычислить сумму и среднее значение элементов в массиве?
У меня проблемы с добавлением всех элементов массива и их усреднением. Как бы я это сделал и реализовал с помощью кода, который у меня сейчас есть? Элементы должны быть определены, как у меня ниже.
<script type="text/javascript">
//<![CDATA[
var i;
var elmt = new Array();
elmt[0] = "0";
elmt[1] = "1";
elmt[2] = "2";
elmt[3] = "3";
elmt[4] = "4";
elmt[5] = "7";
elmt[6] = "8";
elmt[7] = "9";
elmt[8] = "10";
elmt[9] = "11";
// Problem here
for (i = 9; i < 10; i++){
document.write("The sum of all the elements is: " + /* Problem here */ + " The average of all the elements is: " + /* Problem here */ + "<br/>");
}
//]]>
</script>
Ответы
Ответ 1
var sum = 0;
for( var i = 0; i < elmt.length; i++ ){
sum += parseInt( elmt[i], 10 ); //don't forget to add the base
}
var avg = sum/elmt.length;
document.write( "The sum of all the elements is: " + sum + " The average is: " + avg );
Просто перебирайте массив, так как ваши значения являются строками, они сначала должны быть преобразованы в целые числа. И среднее значение - это просто сумма значений, деленная на количество значений.
Ответ 2
Решение, которое я считаю более элегантным:
var sum, avg = 0;
// dividing by 0 will return Infinity
// arr must contain at least 1 element to use reduce
if (arr.length)
{
sum = arr.reduce(function(a, b) { return a + b; });
avg = sum / arr.length;
}
document.write("The sum is: " + sum + ". The average is: " + avg + "<br/>");
Ответ 3
ES6
const average = arr => arr.reduce( ( p, c ) => p + c, 0 ) / arr.length;
const result = average( [ 4, 4, 5, 6, 6 ] ); // 5
console.log(result);
Ответ 4
Вычисление среднего (среднего) с использованием уменьшение и ES6:
const average = list => list.reduce((prev, curr) => prev + curr) / list.length;
const list = [0, 10, 20, 30]
average(list) // 15
Ответ 5
обычно среднее значение с использованием уменьшения одной строки выглядит следующим образом
elements.reduce(function(sum, a,i,ar) { sum += a; return i==ar.length-1?(ar.length==0?0:sum/ar.length):sum},0);
в частности, заданный вопрос
elements.reduce(function(sum, a,i,ar) { sum += parseFloat(a); return i==ar.length-1?(ar.length==0?0:sum/ar.length):sum},0);
эффективная версия похожа на
elements.reduce(function(sum, a) { return sum + a },0)/(elements.length||1);
Понять Javascript Array Уменьшить на 1 минуту
http://www.airpair.com/javascript/javascript-array-reduce
как указал gotofritz, кажется, что Array.reduce пропускает значения undefined.
поэтому вот исправление:
(function average(arr){var finalstate=arr.reduce(function(state,a) { state.sum+=a;state.count+=1; return state },{sum:0,count:0}); return finalstate.sum/finalstate.count})([2,,,6])
Ответ 6
Предположим, что у нас есть массив таких чисел:
var values = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
Среднее значение получается по следующей формуле
A = (1/n) Σxi (с я = 1 до n)... Итак: x1/n + x2/n +... + xn/n
Мы делим текущее значение на количество значений и добавляем предыдущий результат к возвращаемому значению.
Подпись метода уменьшения
reduce(callback[,default_previous_value])
Функция обратного вызова уменьшает следующие параметры:
- p: Результат
предыдущего расчета
- c: текущее значение (из текущего индекса)
- i: текущее значение индекса элемента массива
- a: текущий уменьшенный массив
Второй параметр уменьшения - это значение по умолчанию... (используется, если массив пуст).
Таким образом, средним методом уменьшения будет:
var avg = values.reduce(function(p,c,i,a){return p + (c/a.length)},0);
Если вы предпочитаете, вы можете создать отдельную функцию
function average(p,c,i,a){return p + (c/a.length)};
function sum(p,c){return p + c)};
И тогда просто обратитесь к сигнатуре метода обратного вызова
var avg = values.reduce(average,0);
var sum= values.reduce(sum,0);
Или пропустите прототип массива напрямую.
Array.prototype.sum = Array.prototype.sum || function (){
return this.reduce(function(p,c){return p+c},0);
};
Можно разделить значение каждый раз при вызове метода сокращения.
Array.prototype.avg = Array.prototype.avg || function () {
return this.reduce(function(p,c,i,a){return p+(c/a.length)},0);
};
Или еще лучше, используя ранее определенный Array.protoype.sum()
оптимизируйте процесс, вызывающий деление только один раз:)
Array.prototype.avg = Array.prototype.avg || function () {
return this.sum()/this.length;
};
Затем на любой объект массива области:
[2, 6].avg();// -> 4
[2, 6].sum();// -> 8
NB: пустой массив с возвратом пожелания NaN вернее 0 в моей точке зрения и могут быть полезны в конкретных случаях использования.
Ответ 7
Вы также можете использовать lodash, _.sum (массив) и _.mean (массив) в части Math (также есть другие удобные вещи).
_.sum([4, 2, 8, 6]);
// => 20
_.mean([4, 2, 8, 6]);
// => 5
Ответ 8
Не самая быстрая, но самая короткая и в одной строке использует map() и reduce():
var average = [7,14,21].map(function(x,i,arr){return x/arr.length}).reduce(function(a,b){return a + b})
Ответ 9
Я использую эти методы в своей личной библиотеке:
Array.prototype.sum = Array.prototype.sum || function() {
return this.reduce(function(sum, a) { return sum + Number(a) }, 0);
}
Array.prototype.average = Array.prototype.average || function() {
return this.sum() / (this.length || 1);
}
EDIT:
Чтобы использовать их, просто задайте массив для его суммы или среднего значения, например:
[1,2,3].sum() // = 6
[1,2,3].average() // = 2
Ответ 10
В ES6 готовых браузерах этот polyfill может быть полезным.
Math.sum = (...a) => Array.prototype.reduce.call(a,(a,b) => a+b)
Math.avg = (...a) => this.sum(...a)/a.length;
Вы можете использовать один и тот же метод вызова между Math.sum
, Math.avg
и Math.max
, например:
var maxOne = Math.max(1,2,3,4) // 4;
Вы можете использовать Math.sum как
var sumNum = Math.sum(1,2,3,4) // 10
или если у вас есть массив для суммирования, вы можете использовать
var sumNum = Math.sum.apply(null,[1,2,3,4]) // 10
как
var maxOne = Math.max.apply(null,[1,2,3,4]) // 4
Ответ 11
Один подлый способ, которым вы могли бы это сделать, хотя это требует использования (сильно ненавистного) eval().
var sum = eval(elmt.join('+')), avg = sum / elmt.length;
document.write("The sum of all the elements is: " + sum + " The average of all the elements is: " + avg + "<br/>");
Просто подумал, что я отправлю это как один из этих вариантов "вне коробки". Вы никогда не знаете, хитрость может дать вам (или отнять) точку.
Ответ 12
Вот быстрое добавление к объекту "Math" в javascript для добавления к нему "средней" команды !!
Math.average = function(input) {
this.output = 0;
for (this.i = 0; this.i < input.length; this.i++) {
this.output+=Number(input[this.i]);
}
return this.output/input.length;
}
Тогда у меня есть это дополнение к объекту "Math" для получения суммы!
Math.sum = function(input) {
this.output = 0;
for (this.i = 0; this.i < input.length; this.i++) {
this.output+=Number(input[this.i]);
}
return this.output;
}
Итак, все, что вы делаете, это
alert(Math.sum([5,5,5])); //alerts "15"
alert(Math.average([10,0,5])); //alerts "5"
И где я помещаю массив местозаполнителя, просто передайте вашу переменную (входные данные, если они являются числами, могут быть строкой, потому что она разбирается в число!)
Ответ 13
установите для вашего счетчика циклов значение 0.... вы получаете элемент 9, а затем вы закончите то, что у вас есть сейчас. Другие ответы - основная математика. Используйте переменную для хранения вашей суммы (необходимо передать строки в int) и разделите ее на длину массива.
Ответ 14
Начните с определения всех переменных, которые мы планируем использовать. Вы заметите, что для массива numbers
я использую буквальное обозначение []
в отличие от метода конструктора array()
. Кроме того, я использую более короткий метод для установки нескольких переменных в 0.
var numbers = [], count = sum = avg = 0;
Далее я заполняю свой пустой массив чисел значениями от 0 до 11. Это должно привести меня к исходной отправной точке. Обратите внимание, как я нажимаю на массив count++
. Это приводит к текущему значению счетчика, а затем увеличивает его в следующий раз.
while ( count < 12 )
numbers.push( count++ );
Наконец, я выполняю функцию "для каждого" чисел в массиве чисел. Эта функция будет обрабатывать одно число за раз, которое я определяю как "n" внутри тела функции.
numbers.forEach(function(n){
sum += n;
avg = sum / numbers.length;
});
В конце мы можем выводить как значение sum
, так и значение avg
на нашу консоль, чтобы увидеть результат:
// Sum: 66, Avg: 5.5
console.log( 'Sum: ' + sum + ', Avg: ' + avg );
Смотрите его в действии онлайн http://jsbin.com/unukoj/3/edit
Ответ 15
Я просто опишу ответ Abdennour TOUMI. вот почему:
1.) Я согласен с Брэдом, я не думаю, что это хорошая идея продлить объект, который мы не создали.
2.) array.length
абсолютно надежна в javascript, я предпочитаю Array.reduce
beacuse a=[1,3];a[1000]=5;
, теперь a.length
вернет 1001
.
function getAverage(arry){
// check if array
if(!(Object.prototype.toString.call(arry) === '[object Array]')){
return 0;
}
var sum = 0, count = 0;
sum = arry.reduce(function(previousValue, currentValue, index, array) {
if(isFinite(currentValue)){
count++;
return previousValue+ parseFloat(currentValue);
}
return previousValue;
}, sum);
return count ? sum / count : 0;
};
Ответ 16
В вечнозеленых браузерах вы можете использовать функции стрелок
avg = [1,2,3].reduce((a,b) => (a+b);
Выполняя его 100 000 раз, разница во времени между подходом и сокращением цикла для цикла является незначительной.
s=Date.now();for(i=0;i<100000;i++){ n=[1,2,3]; a=n.reduce((a,b) => (a+b)) / n.length };
console.log("100k reduce took " + (Date.now()-s) + "ms.");
s=Date.now();for(i=0;i<100000;i++){n=[1,2,3]; nl=n.length; a=0; for(j=nl-1;j>0;j--){a=a+n[j];} a/nl };
console.log("100k for loop took " + (Date.now()-s) + "ms.");
s=Date.now();for(i=0;i<1000000;i++){n=[1,2,3]; nl=n.length; a=0; for(j=nl-1;j>0;j--){a=a+n[j];} a/nl };
console.log("1M for loop took " + (Date.now()-s) + "ms.");
s=Date.now();for(i=0;i<1000000;i++){ n=[1,2,3]; a=n.reduce((a,b) => (a+b)) / n.length };
console.log("1M reduce took " + (Date.now()-s) + "ms.");
/*
* RESULT on Chrome 51
* 100k reduce took 26ms.
* 100k for loop took 35ms.
* 10M for loop took 126ms.
* 10M reduce took 209ms.
*/
Ответ 17
Просто для пинков:
var elmt = [0, 1, 2,3, 4, 7, 8, 9, 10, 11], l = elmt.length, i = -1, sum = 0;
for (; ++i < l; sum += elmt[i])
;
document.body.appendChild(document.createTextNode('The sum of all the elements is: ' + sum + ' The average of all the elements is: ' + (sum / l)));
Ответ 18
Вот небольшое небольшое решение для среднего массива, которое очень неэффективно, но имеет очень специфические приложения:
var average = elmt.reduce(function(x,y,z){
return ((x * z) + y) / (z + 1);
});
Документы для метода "уменьшить"
Ответ 19
Array.prototype.avg=function(fn){
fn =fn || function(e,i){return e};
return (this.map(fn).reduce(function(a,b){return parseFloat(a)+parseFloat(b)},0) / this.length ) ;
};
Тогда:
[ 1 , 2 , 3].avg() ; //-> OUT : 2
[{age:25},{age:26},{age:27}].avg(function(e){return e.age}); // OUT : 26
Ответ 20
protected void Submit_Click(object sender, EventArgs e)
{
foreach (ComputerLabReservationList row in db.ComputerLabReservationLists)
{
if (row.LabNo == lblLabNo.Text && row.ReservationDate == StartCld.Text && row.StartEndTime == ddlstartendtime.Text)
{
// string display = "This time have been reserved by others. Please reserve again.";
// ClientScript.RegisterStartupScript(this.GetType(), "yourMessage", "alert('" + display + "');", true);
ScriptManager.RegisterStartupScript(this, this.GetType(),
"alert",
"alert('This time already booked by other. Please insert another time');window.location ='Computerlabs.aspx';",
true);
}
else
{
ComputerLabReservationList crl = new ComputerLabReservationList()
{
ResvId = lblreservationid.Text,
LabNo = lblLabNo.Text,
LecturerId = lblLecturerID.Text,
ReservationDate = StartCld.Text,
StartEndTime = ddlstartendtime.Text
};
db.ComputerLabReservationLists.InsertOnSubmit(crl);
db.SubmitChanges();
ScriptManager.RegisterStartupScript(this, this.GetType(),
"alert",
"alert('Your Reservation was sucessfully');window.location ='MyComputerReservation.aspx';",
true);
}
}
}
Ответ 21
Я думаю, что мы можем сделать как
var k=elmt.reduce(function(a,b){return parseFloat(a+parseFloat(b));})
var avg=k/elmt.length;
console.log(avg);
Я использую parseFloat дважды, потому что
когда
1) вы добавляете (a) 9 + b ( "1" ), тогда результат будет "91", но мы хотим добавить. поэтому я использовал parseFloat
2) Когда добавление (a) 9 + parseFloat ( "1" ) произойдет, результат будет "10", но он будет в строке, которую мы не хотим снова использовать я parseFloat.
Надеюсь, я поняла. Предложения приветствуются
Ответ 22
Вот мой способ новичков просто найти avg. Надеюсь, это поможет кому-то.
function numAvg(num){
var total = 0;
for(var i = 0;i < num.length; i++) {
total+=num[i];
}
return total/num.length;
}
Ответ 23
вот ваш один лайнер:
var average = arr.reduce((sum,item,index,arr)=>index !== arr.length-1?sum+item:sum+item/arr.length,0)
Ответ 24
Я думаю, что это может быть прямое решение для вычисления среднего значения с циклом for и функцией.
var elmts = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
function average(arr) {
var total = 0;
for (var i = 0; i < arr.length; i++) {
total += arr[i];
}
console.log(Math.round(total/arr.length));
}
average(elmts);
Ответ 25
Кажется, существует бесконечное множество решений для этого, но я нашел, что это было кратким и элегантным.
const numbers = [1,2,3,4];
const count = numbers.length;
const reducer = (adder, value) => (adder + value);
const average = numbers.map(x => x/count).reduce(reducer);
console.log(average); // 2.5
Или более точно:
const numbers = [1,2,3,4];
const average = numbers.map(x => x/numbers.length).reduce((adder, value) => (adder + value));
console.log(average); // 2.5
В зависимости от вашего браузера вам может потребоваться выполнить явные вызовы функций, поскольку функции стрелок не поддерживаются:
const r = function (adder, value) {
return adder + value;
};
const m = function (x) {
return x/count;
};
const average = numbers.map(m).reduce(r);
console.log(average); // 2.5
Или же:
const average1 = numbers
.map(function (x) {
return x/count;
})
.reduce(function (adder, value) {
return adder + value;
});
console.log(average1);
Ответ 26
Если вам нужно среднее значение и вы можете пропустить требование расчета суммы, вы можете вычислить среднее значение с помощью одного вызова метода Reduce:
// Assumes an array with only values that can be parsed to a Float
var reducer = function(cumulativeAverage, currentValue, currentIndex) {
// 1. multiply average by currentIndex to find cumulative sum of previous elements
// 2. add currentValue to get cumulative sum, including current element
// 3. divide by total number of elements, including current element (zero-based index + 1)
return (cumulativeAverage * currentIndex + parseFloat(currentValue))/(currentIndex + 1)
}
console.log([1, 2, 3, 4, 5, 6, 7, 8, 9, 10].reduce(reducer, 0)); // => 5.5
console.log([].reduce(reducer, 0)); // => 0
console.log([0].reduce(reducer, 0)); // => 0
console.log([].reduce(reducer, 0)); // => 0
console.log([,,,].reduce(reducer, 0)); // => 0
console.log([].reduce(reducer, 0)); // => 0
Ответ 27
Если кому-то это нужно - вот рекурсивное среднее.
В контексте исходного вопроса вы можете использовать рекурсивное среднее, если вы позволили пользователю вставлять дополнительные значения и, не неся при этом затрат на повторное посещение каждого элемента, хотели "обновить" существующее среднее.
/**
* Computes the recursive average of an indefinite set
* @param {Iterable<number>} set iterable sequence to average
* @param {number} initAvg initial average value
* @param {number} initCount initial average count
*/
function average(set, initAvg, initCount) {
if (!set || !set[Symbol.iterator])
throw Error("must pass an iterable sequence");
let avg = initAvg || 0;
let avgCnt = initCount || 0;
for (let x of set) {
avgCnt += 1;
avg = avg * ((avgCnt - 1) / avgCnt) + x / avgCnt;
}
return avg; // or {avg: avg, count: avgCnt};
}
average([2, 4, 6]); //returns 4
average([4, 6], 2, 1); //returns 4
average([6], 3, 2); //returns 4
average({
*[Symbol.iterator]() {
yield 2; yield 4; yield 6;
}
}); //returns 4
Как:
это работает, поддерживая текущее среднее и количество элементов. Когда нужно добавить новое значение, вы увеличиваете счетчик на 1, масштабируете существующее среднее значение (count-1)/count
и добавляете newValue/count
к среднему.
Выгоды:
- Вы не суммируете все элементы, что может привести к большому количеству, которое не может быть сохранено в 64-битном формате с плавающей запятой.
- Вы можете "обновить" существующее среднее, если станут доступны дополнительные значения.
- Вы можете выполнить скользящее среднее, не зная длины последовательности.
Недостатки:
- влечет за собой гораздо больше подразделений
- не бесконечно - ограничено элементами Number.MAX_SAFE_INTEGER, если вы не используете
BigNumber
Ответ 28
Среднее значение содержимого HTML itens
С jQuery или Javascript querySelector
у вас есть прямая привязка к форматированным данным... Пример:
<p>Elements for an average: <span class="m">2</span>, <span class="m">4</span>,
<span class="m">2</span>, <span class="m">3</span>.
</p>
Итак, с jQuery у вас есть
var A = $('.m')
.map(function(idx) { return parseInt($(this).html()) })
.get();
var AVG = A.reduce(function(a,b){return a+b}) / A5.length;
Смотрите еще 4 способа (!) для доступа к ним и усредняйте его: http://jsfiddle.net/4fLWB/
Ответ 29
var arr = [1,2,3,4,5]
function avg(arr){
var sum = 0;
for (var i = 0; i < arr.length; i++) {
sum += parseFloat(arr[i])
}
return sum / i;
}
avg (arr) ====== → → 3
Это работает со строками в виде чисел или чисел в массиве.
Ответ 30
Простой код может выглядеть так:
var sum = eval("parseInt(" + elmt.join(") + parseInt(") + ");");
var avg = sum / elmt.length;
document.write("The sum of all the elements is: " + sum + " The average of all the elements is: " + avg + "<br/>");
Если вам нужна сводка чисел с плавающей запятой, используйте parseFloat
вместо parseInt
.