Попытка использовать .reduce на объекте - PullRequest
5 голосов
/ 14 июля 2020

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

const json = [
{
    "other_sum": "1",
    "summary": {
        "calculations": {
            "time": 10,
            "unit": 25
        },
        "updated": "2020-06-05"
    }
},
{
    "other_sum": "1",
    "summary": {
        "calculations": {
            "time": 20,
            "unit": 5
        },
        "updated": "2020-06-05"
    }
},
{
    "other_sum": "1",
    "summary": {
        "calculations": {
            "time": 5,
            "unit": 15
        },
        "updated": "2020-06-05"
    }
},
];

Мне нужно просуммировать все "единичные" значения

Я пытался использовать .reduce для этого, но он работает только тогда, когда у меня есть 2 элемента в мой объект, как только я получаю третий, я получаю сообщение об ошибке.

Остальная часть моего кода выглядит следующим образом:

const r = json.reduce((a, b) => a.summary.calculations.unit + b.summary.calculations.unit);
console.log(r);

Не совсем уверен, что я делаю не так, atm.

Ответы [ 4 ]

4 голосов
/ 14 июля 2020

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

Следовательно, значение, вызываемое для следующего элемента, будет быть a.summary.calculations.unit + b.summary.calculations.unit, и в следующий раз ваш обратный вызов будет искать вложенное свойство a.summary.calculations.unit для этого возвращаемого значения, которое предположительно не существует.

Вы можете захотеть изменить его на что-то вроде of:

const r = json.reduce((a, b) => a + b.summary.calculations.unit, 0);

, где 0 - начальное значение для вашего аккумулятора.

MDN , как всегда, является хорошей ссылкой.

4 голосов
/ 14 июля 2020

Потому что reduce работает иначе. Взято из этой статьи , это работает следующим образом:

Учитывая

arrSum = function(arr){
  return arr.reduce(function(a,b){
    return a + b
  }, 0);
}

Функция, которую мы передаем в качестве первого параметра метода уменьшения, получает два параметра , a и b. В этом коде a - наш аккумулятор. Он будет накапливать нашу сумму по мере работы нашей функции. b - текущее обрабатываемое значение.

Итак, в основном вы пытаетесь получить доступ к «сводке» в аккумуляторе, которая представляет собой только число. Вот рабочий фрагмент:

json = [
{
    "other_sum": "1",
    "summary": {
        "calculations": {
            "time": 10,
            "unit": 25
        },
        "updated": "2020-06-05"
    }
},
{
    "other_sum": "1",
    "summary": {
        "calculations": {
            "time": 20,
            "unit": 5
        },
        "updated": "2020-06-05"
    }
},
{
    "other_sum": "1",
    "summary": {
        "calculations": {
            "time": 5,
            "unit": 15
        },
        "updated": "2020-06-05"
    }
},
];

const r = json.reduce((a, b) => a + b.summary.calculations.unit, 0);
console.log(r);
2 голосов
/ 14 июля 2020

Первое значение функции уменьшения - это не объект, а предыдущее возвращаемое значение. Вы можете изменить свой код на этот.

 json.reduce((total, b) => total+ b.summary.calculations.unit, 0);
0 голосов
/ 14 июля 2020

Вы можете использовать мою dig функцию:

function dig(obj, func){
  let v;
  if(obj instanceof Array){
    for(let i=0,l=obj.length; i<l; i++){
      v = obj[i]; func(v, i, obj);
      if(typeof v === 'object')dig(v, func);
    }
  }
  else{
    for(let i in obj){
      v = obj[i]; func(v, i, obj);
      if(typeof v === 'object')dig(v, func);
    }
  }
}
const json = [
  {
    "other_sum": "1",
    "summary": {
      "calculations": {
          "time": 10,
          "unit": 25
      },
      "updated": "2020-06-05"
    }
  },
  {
    "other_sum": "1",
    "summary": {
      "calculations": {
        "time": 20,
         "unit": 5
      },
      "updated": "2020-06-05"
    }
  },
  {
    "other_sum": "1",
    "summary": {
      "calculations": {
        "time": 5,
        "unit": 15
      },
      "updated": "2020-06-05"
    }
  }
];
let unitTotal = 0, timeTotal = 0;
dig(json, (v, k)=>{
  if(k === 'unit'){
    unitTotal += v;
  }
  else if(k === 'time'){
    timeTotal += v;
  }
});
console.log('unitTotal: '+unitTotal);
console.log('timeTotal: '+timeTotal);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...