Манипулировать массивом объектов - PullRequest
0 голосов
/ 22 января 2019

У меня есть массив объектов, который выглядит следующим образом:

var dataArray = [{ "moment": "18 January 2019", "val": 53 },
                 { "moment": "18 January 2019", "val": 69 },
                 { "moment": "18 January 2019", "val": 52 },
                 {"moment": "21 January 2019", "val": 52 },
                 { "moment": "21 January 2019", "val": 52 },
                 { "moment": "21 January 2019", "val": 52 }]

Я хотел бы добавить в новый массив значение элемента moment и среднее значение val на тот момент. например:

result =[{moment: "18 January 2019", "val": 58},
{moment: "21 January 2019", "val": 52}].

На данный момент мне удалось поместить по одному вхождению каждой даты в новый массив результат , но мне трудно определить среднее значение, так как я не знаю, как сделать разницу между значениями для дата из значений для другой даты. Любая помощь будет оценена.

Мир

Ответы [ 6 ]

0 голосов
/ 22 января 2019

const sumRow = (sum, count) => ({ sum, count })

const summarize = data => data.reduce((a, c) => (prev => (
  { ...a, [c.moment]: sumRow(prev.sum + c.val, prev.count + 1) }
))(a[c.moment] || sumRow(0, 0)), {})

const average = summary => Object.keys(summary).map(
  k => ({ moment: k, val: (summary[k].sum / summary[k].count) })
)
 
console.log(average(summarize([
  { "moment": "18 January 2019", "val": 53 },
  { "moment": "18 January 2019", "val": 69 },
  { "moment": "18 January 2019", "val": 52 },
  { "moment": "21 January 2019", "val": 52 },
  { "moment": "21 January 2019", "val": 52 },
  { "moment": "21 January 2019", "val": 52 }
])))
0 голосов
/ 22 января 2019

Использовать массив уменьшить и внутри обратного вызова проверить, есть ли у массива arument момент с тем же значением

var dataArray = [{
    "moment": "18 January 2019",
    "val": 53
  },
  {
    "moment": "18 January 2019",
    "val": 69
  },
  {
    "moment": "18 January 2019",
    "val": 52
  },
  {
    "moment": "21 January 2019",
    "val": 52
  },
  {
    "moment": "21 January 2019",
    "val": 52
  },
  {
    "moment": "21 January 2019",
    "val": 52
  }
]

let avgVal = dataArray.reduce(function(acc, curr) {
  let findIfHasDate = acc.findIndex((item) => {
    return item.moment === curr.moment

  });

  if (findIfHasDate === -1) {
    acc.push({
      moment: curr.moment,
      totalVal: curr.val,
      totalcount: 1

    })
  } else {
    acc[findIfHasDate].totalVal = (acc[findIfHasDate].totalVal + curr.val);
    acc[findIfHasDate].totalcount += 1;
  }

  return acc;
}, []).map((item) => {
  return {
    moment: item.moment,
    avg: (item.totalVal) / item.totalcount
  }
})

console.log(avgVal)
0 голосов
/ 22 января 2019

Вы можете получить ожидаемый результат следующим образом, используя уменьшить

var dataArray = [{
        "moment": "18 January 2019",
        "val": 53
    },
    {
        "moment": "18 January 2019",
        "val": 69
    },
    {
        "moment": "18 January 2019",
        "val": 52
    },
    {
        "moment": "21 January 2019",
        "val": 52
    },
    {
        "moment": "21 January 2019",
        "val": 52
    },
    {
        "moment": "21 January 2019",
        "val": 52
    }
];

const result = dataArray.reduce((accumulator, currentValue, index, array) => {
    if (!accumulator[currentValue.moment]) {
        accumulator[currentValue.moment] = array
            .filter(arr => arr.moment === currentValue.moment)
            .reduce((acc, val, idx, coll) => {
                acc += val.val;

                if (idx === coll.length - 1) {
                    return acc/coll.length;
                } else {
                    return acc;
                }
        }, 0);
    }

    return accumulator;
}, []);

console.log(result); // [ '18 January 2019': 58, '21 January 2019': 52 ]
0 голосов
/ 22 января 2019

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

const dataArray = [{ "moment": "18 January 2019", "val": 53 },
                   { "moment": "18 January 2019", "val": 69 },
                   { "moment": "18 January 2019", "val": 52 },
                   { "moment": "21 January 2019", "val": 52 },
                   { "moment": "21 January 2019", "val": 52 },
                   { "moment": "21 January 2019", "val": 52 }]
                   
const groups = dataArray.reduce((r, { moment, val }) => {
  (r[moment] = r[moment] || []).push(val)  
  return r
}, {})

const avg = arr => arr.reduce((r, x) => r + x, 0) / arr.length

const result = Object.entries(groups).map(([moment, arr]) => ({
  moment,
  avg: avg(arr)
}))

console.log(result)

  
0 голосов
/ 22 января 2019

Вы можете сделать это, используя уменьшить .

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

var dataArray = [{ "moment": "18 January 2019","val": 53 },{ "moment": "18 January 2019", "val": 69 },{ "moment": "18 January 2019", "val": 52 },{"moment": "21 January 2019", "val": 52 },                { "moment": "21 January 2019", "val": 52 },                { "moment": "21 January 2019", "val": 52 }]
                 
let output = dataArray.reduce((op,cur)=>{
  if( op[cur.moment] ){
    op[cur.moment].val += cur.val;
    op[cur.moment].count++;
  } else {
    op[cur.moment] = cur
    op[cur.moment].count = 1;
  }
  return op;
},{})

let final = Object.values(output).map(e => {
   return {
    moment: e.moment,
    val: e.val/e.count
   } 
})

console.log(final)
0 голосов
/ 22 января 2019
var totalCount = 0;
var divBy = 0;
var momentToCheck = "21 January 2019"
for(int i= 0; i<dataArray.length; i++) {
    if (dataArray[i].moment === momentToCheck) {
        totalCount+= dataArray[i].val;
        divBy++;
    }
}
var newAvg = totalCount/divBy;
dataArray.push({moment:momentToCheck, val:newAvg});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...