Как сделать статистическую классификацию по массиву в javascript? - PullRequest
0 голосов
/ 21 декабря 2011

У меня есть куча чисел в массиве, и мне нужно сделать статистику по ним. Мне нужно знать, сколько каждого числа есть в массиве.

Вот массив:

myArray =
[2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 15, 15, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 27, 27, 28, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 34, 34, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 40, 40, 40, 41, 41, 42, 42, 42, 42, 42, 42, 43, 43, 43, 44, 44, 44, 44, 44, 45, 45, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 52, 52, 53, 53, 53, 53, 53, 53, 53, 54, 54, 54, 55, 55, 55, 55, 55, 56, 57, 57, 57, 57, 57, 57, 57, 58, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 61, 61, 62, 62, 63, 63, 63, 64, 64, 64, 64, 64, 65, 65, 66, 66, 66, 67, 67, 67, 68, 68, 68, 69, 69, 69, 69, 69, 69, 70, 70, 71, 71, 71, 71, 71, 71, 71, 72, 73, 73, 73, 73, 74, 74, 74, 75, 75, 75, 76, 77, 78, 78, 79, 79, 80, 80, 81, 81, 81, 81, 81, 82, 82, 82, 82, 83, 83, 83, 83, 84, 84, 84, 85, 85, 85, 85, 85, 86, 86, 86, 86, 86, 86, 87, 87, 87, 88, 88, 89, 89, 90, 90, 91, 91, 91, 92, 93, 94, 95, 95, 95, 95, 95, 96, 96, 96, 96, 97, 97, 99, 99, 99, 99, 99, 101, 101, 102, 102, 103, 103, 105, 105, 105, 106, 107, 107, 108, 108, 109, 109, 109, 109, 110, 112, 112, 113, 113, 113, 114, 114, 115, 116, 116, 117, 118, 120, 121, 121, 121, 122, 122, 123, 123, 123, 124, 124, 124, 124, 125, 126, 127, 128, 129, 130, 130, 131, 131, 131, 131, 132, 133, 133, 134, 134, 134, 136, 136, 136, 136, 137, 137, 137, 138, 138, 138, 139, 139, 139, 140, 141, 141, 142, 142, 143, 144, 144, 144, 144, 145, 150, 150, 153, 155, 159, 160, 160, 161, 162, 164, 164, 166, 176, 180, 180, 180, 181, 181, 187, 191, 192, 193, 194, 197, 200, 203, 211, 216, 224, 251, 280, 333]

Вот что я сейчас использую для его анализа (что не очень хорошо работает):

    for (var key in myArray){
        var obj = myArray[key];

        var count = 0;
        while(obj < 30){
            myArrayStats[0] = count;
            obj++;
        }
        while(obj > 30 && obj < 40){
            myArrayStats[1] = count;
            obj++;
        }
        //etc....
    }

Создание нового массива с использованием объектных литералов было бы намного приятнее и проще в использовании, но я не уверен, как это сделать.

Ответы [ 3 ]

4 голосов
/ 21 декабря 2011

Это просто работает независимо от того, отсортирован ли ваш массив или нет, но он не должен быть намного медленнее, чем любой алгоритм, который использует тот факт, что он сортируется в любом случае:

var myArrayStats = [];
for(var i = myArray.length; i--;)
    myArrayStats[myArray[i]] = (myArrayStats[myArray[i]] || 0) + 1;

console.log(myArrayStats[6]);  // Outputs 7
console.log(myArrayStats[10]); // Outputs 5
console.log(myArrayStats[20]); // Outputs 5

Если вы хотитесделать это только для части исходного массива, чем использовать slice () , чтобы получить нужную часть массива, а затем сделать то же самое, что и выше для этого массива:

var mySubArray = myArray.slice(0,30);
var myArrayStats = [];
for(var i = mySubArray.length; i--;)
    myArrayStats[mySubArray[i]] = (myArrayStats[mySubArray[i]] || 0) + 1;

console.log(myArrayStats[6]);  // Outputs 7
console.log(myArrayStats[9]);  // Outputs 7
console.log(myArrayStats[10]); // Outputs undefined
0 голосов
/ 17 января 2019

myArray = [2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 8,
  8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11,
  11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 14, 14]

for (var a = myArray, b = {}, i = 0; i < myArray.length; i++) b[a[i]] ? b[a[i]]++ : b[a[i]] = 1;
console.log(JSON.stringify(Object.keys(b)
  .map(function(c) {
    return [c, b[c]]
  })));
0 голосов
/ 21 декабря 2011

Звучит так, как будто у вас одинаковые интервалы и вы хотите посчитать, сколько значений попадает в каждый.Поскольку этот вопрос был помечен с помощью jQuery, давайте воспользуемся утилитой из этого, чтобы избежать явного цикла, чтобы показать другой способ сделать что-то.(Я полагаю, что подход PaulPRO является превосходным.)

function hist(values, min, max, numBins) {
    var bins = [];
    var range = max - min;
    jQuery.each(values, function(i, value) {
        var bin = Math.floor(numBins * (value - min) / range);
        bin = Math.min(Math.max(bin, -1), numBins) + 1;
        bins[bin] = (bins[bin] || 0) + 1;
    });
    return bins;
}

Мы можем использовать приведенный выше код следующим образом:

function consoleHist(values, min, max, numBins) {
    var bins = hist(values, min, max, numBins);
    var step = (max - min) / numBins;
    jQuery.each(bins, function(i, count) {
        var lower = (i - 1) * step + min;
        var upper = lower + step;
        if (lower < min) {
            lower = -Infinity;
        }
        if (upper > max) {
            upper = Infinity;
        }
        console.log('[' + lower + ', ' + upper + '): ' + (count || 0));
    });
}

consoleHist([-10, 0, 11, 29, 30, 59, 60, 1000], 0, 60, 2);

Создает следующий вывод на консоль:

[-Infinity, 0): 1
[0, 30): 3
[30, 60): 2
[60, Infinity): 2
...