Суммирование только числовых свойств объекта

Я создал метод, который возвращает несколько mappedObject, которые содержат идентификатор и ежедневно регистрируемые часы.

Это код, который возвращает сопоставление:

 return Object.keys(tableData).map(key => {
      const mappedObject = {
        id: key
      };
      tableData[key].forEach(weekday => {
          mappedObject[weekday.day] = Math.round( (weekday.spent / 3600) * 10) / 10;
      });
      return mappedObject;
    });

вот возвращенные mappedObjects:

{id: "c94.33", MON: 8, WED: 3.2, FRI: 5.3}
{id: "c.005.001", THU: 8}
{id: "unspecified", TUE: 8, WED: 4.8, FRI: 2.7}

Как сделать подсуммы часов под каждым идентификатором?

Например:

с94,33 : 16,5

с.005.001:8

не указано: 15,5

Моя идея и то, что я пробовал: -создать массив и вставить в массив значения mappedObject.

    return Object.keys(tableData).map(key => {
      const mappedObject = {
        id: key
      };
      tableData[key].forEach(weekday => {
          mappedObject[weekday.day] = Math.round( (weekday.spent / 3600) * 10) / 10;
          this.totalHoursPerid.push(_.sum(_.values(mappedObject)));
          console.log(this.totalHoursPerid);
      });
      return mappedObject;
    });
  }

это не работает, потому что ключ id имеет строковое значение (по крайней мере, я так думаю).

Как указано в комментариях, это tableData, который анализируется:

{c94.33:
 [{day: "MON", spent: 28800},
  {day: "WED", spent: 11400},
  {day: "FRI", spent: 19200}],
c.005.001: 
 [{day: "THU", spent: 28800}],
unspecified:
 [{day: "TUE", spent: 28800},
  {day: "WED", spent: 17400},
  {day: "FRI", spent: 9600}]
}

Можете ли вы показать исходный пример ввода тоже?

Andy 22.05.2019 12:33

Можете ли вы также показать tableData, которые вы вводите?

Sachintha Nayanajith 22.05.2019 12:37

добавлено внутри поста

jsbeginner 22.05.2019 12:43

потраченное поле - это время в секундах, и я преобразовал его в часы + минуты

jsbeginner 22.05.2019 12:44
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
0
4
57
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Вы можете использовать reduce. Извлеките id, а затем вы можете применить Object.values для получения значений других свойств.

const input = [
    {id: "c94.33", MON: 8, WED: 3.2, FRI: 5.3}, 
    {id: "c.005.001", THU: 8}, 
    {id: "unspecified", TUE: 8, WED: 4.8, FRI: 2.7}
];

const output = input.reduce((accu, {id, ...rest}) => {
    accu[id] = Object.values(rest).reduce((accu, val) => accu + val, 0);
    return accu;
}, {});

console.log(output);

Вы также можете использовать map,

const input = [
    {id: "c94.33", MON: 8, WED: 3.2, FRI: 5.3}, 
    {id: "c.005.001", THU: 8}, 
    {id: "unspecified", TUE: 8, WED: 4.8, FRI: 2.7}
];

const output = input.map(({id, ...rest}) => ({[id]: Object.values(rest).reduce((accu, val) => accu + val, 0)}));
console.log(output);

const tableData = {
    "c94.33": [
        {day: "MON", spent: 28800},
        {day: "WED", spent: 11400},
        {day: "FRI", spent: 19200}
    ],
    "c.005.001": [
        {day: "THU", spent: 28800}
    ],
   "unspecified":[
       {day: "TUE", spent: 28800},
       {day: "WED", spent: 17400},
       {day: "FRI", spent: 9600}
    ]
}

const output = Object.entries(tableData).map(([key, val]) => {
    const sum = val.reduce((accu, {spent}) => {
        accu = accu + Math.round( (spent / 3600) * 10) / 10;
        return accu;
    }, 0)
    return ({[key]: sum})
});

console.log(output);

Я попробовал ваш фрагмент, и он показывает эту ошибку: «Свойство 'reduce' не существует для типа '{id: string; }'» и это: «Оператор '+' не может быть применен к типам '{}' и '{} '" при попытке добавить значение (при втором уменьшении)

jsbeginner 22.05.2019 12:55

«return mappedObject» в моем коде возвращает один объект, а не массив объектов.

jsbeginner 22.05.2019 13:00

Не могли бы вы добавить свой объект? reduce и map работают с массивом. Было бы здорово, если бы вы могли добавить свой объект ввода.

random 22.05.2019 13:00

Вы имеете в виду tableData? Я добавил его в сообщение

jsbeginner 22.05.2019 13:05

let tableData = {"c94.33":
    [{day: "MON", spent: 28800},
     {day: "WED", spent: 11400},
     {day: "FRI", spent: 19200}],
   "c.005.001": 
    [{day: "THU", spent: 28800}],
   "unspecified":
    [{day: "TUE", spent: 28800},
     {day: "WED", spent: 17400},
     {day: "FRI", spent: 9600}]
   }


console.log( Object.keys(tableData).map(key => {
    const mappedObject = {};
      
    var spenttime = 0
    tableData[key].forEach(weekday => {
        spenttime  += Math.round( (weekday.spent / 3600) * 10) / 10;
    });

    mappedObject[key] = spenttime
    return mappedObject;
}));

Вы можете объединить все это и вычислить суммы за дни, когда вы создаете новый вывод:

const tableData = {"c94.33":[{"day":"MON","spent":28800},{"day":"WED","spent":11400},{"day":"FRI","spent":19200}],"c.005.001":[{"day":"THU","spent":28800}],"unspecified":[{"day":"TUE","spent":28800},{"day":"WED","spent":17400},{"day":"FRI","spent":9600}]};

const calc = spent => Math.round((spent / 3600) * 10) / 10;

// Iterate over the object entries
const out = Object.entries(tableData).reduce((acc, [key, dayArr]) => {

  // `map` over the day array to calculate the spend
  const days = dayArr.map(({ day, spent }) => ({ [day]: calc(spent) }));

  // Use that array to calculate the sum
  const spent = days.reduce((acc, obj) => acc + Object.values(obj)[0], 0);

  // Create and return a new object
  acc[key] = { days, spent };
  return acc;
}, {});

console.log(out);

Другие вопросы по теме