Вычисление общего среднего многомерного массива в JavaScript - PullRequest
0 голосов
/ 03 ноября 2011

Как мне рассчитать среднее значение всех значений в многомерном массиве?Я написал функцию для вычисления среднего значения из одномерного массива, но я не уверен, какой метод лучше использовать, когда имеется более 1-мерного.

Например, допустим, у нас естьследующее:

var A = Array(3);
for (i=0; i<A.length; i++) {
    A[i] = new Array(2);
    for (j=0; j<A[i].length; j++) {
        A[i][j] = i+j;
    }
}

Следовательно, A - это двумерный массив или матрица 3x2:

A = 0   1
    1   2
    2   3

Поэтому я хотел бы найти среднее значение всех значений, котороев этом случае будет равно 1,5.Я предполагаю, что мне нужно создать новый одномерный массив всех значений, которые я мог бы затем добавить в свою функцию усреднения.Тем не менее, я не уверен, что самый простой способ сделать это, когда массив является многомерным (например, 5x3x6x9).

Спасибо!

EDIT

Спасибо всем!Я воспользовался вашим советом и сгладил массив, используя код, который я нашел в одной из прикрепленных ссылок, которая использует функцию Reduce.Моя функция усреднения теперь выглядит так:

function average(x) {

    // Flatten multi-dimensional array
    while (x[0] instanceof Array) {
        x = x.reduce( function(a, b) { return a.concat(b); } );
    }

    // Calculate average
    return x.reduce( function(a, b) { return a + b; } )/x.length;
}

Ответы [ 4 ]

1 голос
/ 03 ноября 2011

// Самый простой способ - сгладить массив

Array.prototype.flatten= function(){
var A= [];
this.forEach(function(itm){
    if(!itm || !itm.flatten)A.push(itm);
    else{
        A= A.concat(itm.flatten());
    }
});
return A;
}
// shim for older browsers (without array forEach)
Array.prototype.forEach= [].forEach || function(fun, scope){
    var T= this, L= T.length, i= 0;
    if(typeof fun== 'function'){
        while(i< L){
            if(i in T){
                fun.call(scope, T[i], i, T);
            }
            ++i;
        }
    }
    return T;
}

var a=[[1,2,3,[1,2,3]],[4,5,6,[7,8,[1,2,3,[1,2]]]],11,[1,[2,[2,4,[5]]]]];
a.flatten().join('\n')

/*  returned value: (String)
1
2
3
1
2
3
4
5
6
7
8
1
2
3
1
2
11
1
2
2
4
5
*/
1 голос
/ 03 ноября 2011

Я не вижу особой причины, по которой вам нужно создавать новый массив. Просто переберите те, которые у вас есть:

var i, j, sub, total, count, avg;

total = count = 0;
for (i = 0; i < A.length; ++i) {
    sub = A[i];
    count += sub.length;
    for (j = 0; j < sub.length; ++j) {
        total += sub[j];
    }
}
avg = count === 0 ? NaN : total / count;

Обратите внимание, что в приведенном выше примере предполагается, что массивы не редки (в вашем примере их нет).

1 голос
/ 03 ноября 2011

Вы можете сгладить ваш многомерный массив с помощью этой функции:

function flatten(arr) {
    var acc = [];
    var f = function(arr) {
        for (var i = 0; i < arr.length; ++i) {
            if (arr[i] instanceof Array) {
                f(arr[i]);
            }
            else {
                acc.push(arr[i]);
            }
        }
    };
    f(arr);
    return acc;
}

И затем вы можете рассчитать среднее значение с помощью вашей функции.

1 голос
/ 03 ноября 2011

Вы можете использовать этот код , чтобы сгладить многомерный массив:

function flatten(array){
    var flat = [];
    for (var i = 0, l = array.length; i < l; i++){
        var type = Object.prototype.toString.call(array[i]).split(' ').pop().split(']').shift().toLowerCase();
        if (type) { flat = flat.concat(/^(array|collection|arguments|object)$/.test(type) ? flatten(array[i]) : array[i]); }
    }
    return flat;
}

, а затем просто сложите и разделите:

var total = 0;
for (var i = 0, l = flattenedArray.length; i<l; i++) {
  total += flattenedArray[i];
}
var average = total/flattenedArray.length;
...