У меня есть следующая структура данных, и мне нужно получить среднее значение для каждого из столбцов для элементов в объекте contenders. Затем мне нужно превратить это в массив массивов. Первое значение должно быть средним по столбцам (округлено), второе должно быть увеличенным значением, начиная с 0. Например,

output = [[6, 0], [4, 1], [3, 2], [3, 3], [6, 4]]; 

Пример структуры:

input = {
  categories: [
    "Cat 1",
    "Cat 2",
    "Cat 3",
    "Cat 4",
    "Cat 5"
  ],
  contenders: {
    item1:       [5, 3, 4, 4, 6],
    item2:       [6, 10, 4, 4, 6],
    item3:       [6, 3, 4, 9, 6],
    item4:       [8, 3, 5, 4, 6],
    item5:       [9, 3, 4, 4, 6],
    item6:       [10, 2, 7, 4, 6],
    item7:       [4, 3, 4, 4, 6],
    item8:       [1, 5, 4, 4, 6]
  },
  misc: [0, 3, 4, 4, 6]
};

Я создал функцию, которая может сделать среднее для меня:

function getAvg(data) {
    return data.reduce(function (p, c) {
                return p + c;
            }) / data.length;
} 

Но не могу понять, как перебрать значения для элементов, чтобы получить мой результат.

3
user1513388 17 Дек 2015 в 16:41

4 ответа

Лучший ответ

Вы можете использовать Object.keys для получения свойств, а затем перебирать значения с помощью Array.prototype.forEach.

var input = { categories: ["Cat 1", "Cat 2", "Cat 3", "Cat 4", "Cat 5"], contenders: { item1: [5, 3, 4, 4, 6], item2: [6, 10, 4, 4, 6], item3: [6, 3, 4, 9, 6], item4: [8, 3, 5, 4, 6], item5: [9, 3, 4, 4, 6], item6: [10, 2, 7, 4, 6], item7: [4, 3, 4, 4, 6], item8: [1, 5, 4, 4, 6] }, misc: [0, 3, 4, 4, 6] },
    output = [],
    sum = [], count = [];

Object.keys(input.contenders).forEach(function (k) {
    input.contenders[k].forEach(function (a, i) {
        sum[i] = (sum[i] || 0) + a;
        count[i] = (count[i] || 0) + 1;
    });
});
output = sum.map(function (a, i) {
    return [Math.round(sum[i] / count[i]), i]
});

document.write('<pre>' + JSON.stringify(output, 0, 4) + '</pre>');
0
Nina Scholz 17 Дек 2015 в 14:00

Вы должны полностью использовать Object.keys, как предложено в других ответах. Однако, для полноты или маловероятного случая, что совместимость доставляет вам проблемы: Вы можете построить строку для ссылки на массивы, которые вы ищете, вот так

for (var i=1;i<9;i++) { doSomething(input.contenders["item"+i]); }

Это потребует от вас заранее знать количество предметов и их названия.

0
icke 17 Дек 2015 в 13:59

Вы можете использовать комбинацию Object.keys чтобы получить каждый элемент в contenders, затем используйте map, чтобы создать новый массив из результатов:

function getAvg(data) {
  return data.reduce(function (p, c) {
    return p + c;
  }) / data.length;
} 
var input = {
  categories: [
    "Cat 1",
    "Cat 2",
    "Cat 3",
    "Cat 4",
    "Cat 5"
  ],
  contenders: {
    item1:       [5, 3, 4, 4, 6],
    item2:       [6, 10, 4, 4, 6],
    item3:       [6, 3, 4, 9, 6],
    item4:       [8, 3, 5, 4, 6],
    item5:       [9, 3, 4, 4, 6],
    item6:       [10, 2, 7, 4, 6],
    item7:       [4, 3, 4, 4, 6],
    item8:       [1, 5, 4, 4, 6]
  },
  misc: [0, 3, 4, 4, 6]
};
console.log(Object.keys(input.contenders).map(function(key, index) {
  return [getAvg(input.contenders[key]), index];
}));
1
CodingIntrigue 17 Дек 2015 в 13:50

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

      var input = { categories: ["Cat 1", "Cat 2", "Cat 3", "Cat 4", "Cat 5"], contenders: { item1: [5, 3, 4, 4, 6], item2: [6, 10, 4, 4, 6], item3: [6, 3, 4, 9, 6], item4: [8, 3, 5, 4, 6], item5: [9, 3, 4, 4, 6], item6: [10, 2, 7, 4, 6], item7: [4, 3, 4, 4, 6], item8: [1, 5, 4, 4, 6] }, misc: [0, 3, 4, 4, 6] }


    var output = []

    var cols = input.contenders.item1.length // amount of columns (I assume all items have same amount of columns)

    for(var i=0;i<cols;i++){
      output[i] = [0,i] // start output with sum of 0 and index i
    }

    for(var key in input.contenders){
      var arr = input.contenders[key]
      for(var k = 0;k<cols;k++){
        output[k][0]+=arr[k] // add the value of the array in the kth position to the kth output sum
      }
    }

    for(var i=0;i<cols;i++){
      output[i][0] = Math.round(output[i][0]/Object.keys(input.contenders).length) // now just divide by the amount of keys
    }

    console.log(output)
2
juvian 17 Дек 2015 в 13:58