JavaScript сумма значений через объект

1

Я возвращаю данные JSON из API. Затем я использую карту для создания своего собственного объекта.

Данные имеют несколько объектов. Вот пример:

{
  "data": {
    "job": [
      {
        "jobNumber": "1",
        "jobTasks": {
          "jobTask": [
            {
              "total": { "amountString": "10.00" }
            },
            {
              "total": { "amountString": "10.00" }
            }
          ]
        }
      },
      {
        "jobNumber": "2",
        "jobTasks": {
          "jobTask": [
            {
              "total": { "amountString": "20.00" }
            },
            {
              "total": { "amountString": "20.00" }
            }
          ]
        }
      },
      {
        "jobNumber": "3",
        "jobTasks": {
          "jobTask": [
            {
              "total": { "amountString": "30.00" }
            },
            {
              "total": { "amountString": "30.00" }
            }
          ]
        }
      }
    ]
  }
}

Как из этого возвращенного примера, я хочу иметь следующее:

№ работы: 1: Всего 20. номер работы: 2: всего 40. номер работы: 3: всего 60.

Вот код, который я использую:

var array = response.data.map(function(item, array) {

   var sumTaskTotal = item.jobTasks.reduce(function(sumTaskTotal, item, index) {
       if (item !== null && item.total !== null) {
          sumTaskTotal += item.total.amountString;
          return sumTaskTotal;
       }
    }, 0);

    array = response.data.map(item => ({
      jobNumber: item.jobNumber,
      sumTaskTotal: sumTaskTotal,
    }));
}

Однако сумма, которую я использую, просто суммирует, поэтому я получаю:

jobNumber: 1: Всего 120. jobNumber: 120: Всего 120. jobNumber: 3: Всего 120.

Я пробовал циклы, но, похоже, я нигде не попадал.

  • 0
    Добавьте JSON в посте также ..
  • 0
    Вам нужен массив { jobNumber: Number, sumTaskTotal: Number } или строка jobNumber: 1: Total 20. jobNumber: 2: Total 40. jobNumber: 3: Total 60. ?
Показать ещё 1 комментарий
Теги:
object
mapreduce

2 ответа

1

На самом деле не уверен, как вы получили jobNumber: 1: Total 120. jobNumber: 120: Total 120. jobNumber: 3: Total 120... Я пробовал ваш код, и когда вы регистрируете массив, вы просто получите array with 3 undefined items; каждая итерация на map в вашем коде не возвращает ничего, поэтому массив содержит 3 не определенных элемента.

Кроме того, data и jobTasks - это объекты. Вы должны использовать map или reduce свойства job и свойства jobTask.

Что касается добавления итогов, amountString - string (очевидно), и вы должны сначала преобразовать ее в число. В противном случае результат в вашей первой итерации будет 010.00 так как вы объединяете string в number. Он не добавляет 0 и 10.00.

array = response.data.map... часть вашей внешней карты просто повторит все задания. Каждая итерация на map ожидает возврата элемента. Если вы ничего не вернете, undefined будет значение этого массива. Поэтому вместо того, чтобы снова отображать массив, вы можете просто сделать это:

return {
  jobNumber: item.jobNumber,
  sumTaskTotal,
};

Тогда это приведет к массиву с 3 объектами:

[{
  jobNumber: '1',
  sumTaskTotal: 20,
}, {
  jobNumber: '2',
  sumTaskTotal: 40,
}, {
  jobNumber: '3',
  sumTaskTotal: 60,
}]

Но вместо этого вы можете сделать nested reduce:

const formatted = response.data.job.reduce((prevString, currentJob) => {
  const total = currentJob.jobTasks.jobTask.reduce((prevTotal, currentJobTask) => {
    return prevTotal + Number(currentJobTask.total.amountString);
  }, 0);

  return '${prevString}jobNumber: ${currentJob.jobNumber}: Total ${total}. ';
}, '');

const response = {
  "data": {
    "job": [{
      "jobNumber": "1",
      "jobTasks": {
        "jobTask": [{
          "total": {
            "amountString": "10.00"
          }
        }, {
          "total": {
            "amountString": "10.00"
          }
        }]
      }
    }, {
      "jobNumber": "2",
      "jobTasks": {
        "jobTask": [{
          "total": {
            "amountString": "20.00"
          }
        }, {
          "total": {
            "amountString": "20.00"
          }
        }]
      }
    }, {
      "jobNumber": "3",
      "jobTasks": {
        "jobTask": [{
          "total": {
            "amountString": "30.00"
          }
        }, {
          "total": {
            "amountString": "30.00"
          }
        }]
      }
    }]
  }
};

const formatted = response.data.job.reduce((prevString, currentJob) => {
	const total = currentJob.jobTasks.jobTask.reduce((prevTotal, currentJobTask) => {
  	return prevTotal + Number(currentJobTask.total.amountString);
  }, 0);
  
  return '${prevString}jobNumber: ${currentJob.jobNumber}: Total ${total}. ';
}, '');

console.log(formatted.trim());
0

вы можете использовать только для forEach чтобы получить нужную строку.

const data = {
  "data": {
    "job": [
      --
    ]
  }
}

let string = "";

data.data.job.forEach((item) => {
  const sum = item.jobTasks.jobTask.reduce((total, i) => parseFloat(i.total.amountString) + total, 0);
  string += 'jobNumber: ${item.jobNumber}: Total ${sum}. ';  
});
console.log(string);

jsbin

после вашей строки будет ненужное пространство. использование отделка функция если необходимо.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню