Объединение двух наборов данных и вычисление разных значений

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

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

Затем из dataTwo мне нужно включить количество кликов для каждого типа.

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

const ob = {
  "dataOne": [
    {
      "type": "Type 1",
      "name": "failed"
    },
    {
      "type": "Type 1",
      "name": "success"
    },
    {
      "type": "Type 2",
      "name": "success"
    },
    {
      "type": "Type 3",
      "name": "success"
    },
  ],
  "dataTwo": [
    {
      "type": "Type 1",
      "name": "click",
    },
    {
      "type": "Type 2",
      "name": "click",
    },
    {
      "type": "Type 2",
      "name": "click",
    },
    {
      "type": "Type 1",
      "name": "click",
    },
    {
      "type": "Type 3",
      "name": "click",
    },
  ]
};

const dataOneReduced = ob.dataOne.reduce((acc, o) => {
  if (!acc[o.type]) {
    acc[o.type] = [
      {
        count: 0,
        success: 0,
        failed: 0,
        click: 0,
      },
    ];
  }

  acc[o.type][0]["count"] = (acc[o.type][0]["count"] || 0) + 1;
  acc[o.type][0][o.name] = acc[o.type][0][o.name] + 1;

  return acc;
}, {});

const result = ob.dataTwo.reduce((acc, o) => {
  acc[o.type][0][o.name] = acc[o.type][0][o.name] + 1;

  return acc;
}, dataOneReduced);

console.info(result);

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

{
  "Type 1": [
    {
      "count": 2,
      "success": 1,
      "failed": 1,
      "click": 2,
      "successPecentage": 50
    }
  ],
  "Type 2": [
    {
      "count": 1,
      "success": 1,
      "failed": 0,
      "click": 2,
      "successPecentage": 100
    }
  ],
  "Type 3": [
    {
      "count": 1,
      "success": 1,
      "failed": 0,
      "click": 1,
      "successPecentage": 100,
    }
  ]
}

Как бы я этого добился?

Спасибо

Во втором .reduce (где стоит result) добавьте эту строку: acc[o.type][0].successPercentage = Math.round(acc[o.type][0].success / acc[o.type][0].count * 100);

jsN00b 10.04.2022 17:26
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
1
29
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Желаемая цель может быть достигнута путем добавления одной строки: acc[o.type][0].successPercentage = Math.round(acc[o.type][0].success / acc[o.type][0].count * 100); как показано в приведенном ниже фрагменте

Фрагмент кода

const ob = {
  "dataOne": [
    {
      "type": "Type 1",
      "name": "failed"
    },
    {
      "type": "Type 1",
      "name": "success"
    },
    {
      "type": "Type 2",
      "name": "success"
    },
    {
      "type": "Type 3",
      "name": "success"
    },
  ],
  "dataTwo": [
    {
      "type": "Type 1",
      "name": "click",
    },
    {
      "type": "Type 2",
      "name": "click",
    },
    {
      "type": "Type 2",
      "name": "click",
    },
    {
      "type": "Type 1",
      "name": "click",
    },
    {
      "type": "Type 3",
      "name": "click",
    },
  ]
};

const dataOneReduced = ob.dataOne.reduce((acc, o) => {
  if (!acc[o.type]) {
    acc[o.type] = [
      {
        count: 0,
        success: 0,
        failed: 0,
        click: 0,
      },
    ];
  }

  acc[o.type][0]["count"] = (acc[o.type][0]["count"] || 0) + 1;
  acc[o.type][0][o.name] = acc[o.type][0][o.name] + 1;

  return acc;
}, {});

const result = ob.dataTwo.reduce((acc, o) => {
  acc[o.type][0][o.name] = acc[o.type][0][o.name] + 1;
  acc[o.type][0].successPercentage = Math.round(acc[o.type][0].success / acc[o.type][0].count * 100);
  return acc;
}, dataOneReduced);

console.info(result);
Ответ принят как подходящий

Опция 1

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

const ob = {
  "dataOne": [
    {
      "type": "Type 1",
      "name": "failed"
    },
    {
      "type": "Type 1",
      "name": "success"
    },
    {
      "type": "Type 2",
      "name": "success"
    },
    {
      "type": "Type 3",
      "name": "success"
    },
  ],
  "dataTwo": [
    {
      "type": "Type 1",
      "name": "click",
    },
    {
      "type": "Type 2",
      "name": "click",
    },
    {
      "type": "Type 2",
      "name": "click",
    },
    {
      "type": "Type 1",
      "name": "click",
    },
    {
      "type": "Type 3",
      "name": "click",
    },
  ]
};

const dataOneReduced = ob.dataOne.reduce((acc, o) => {
  if (!acc[o.type]) {
    acc[o.type] = [
      {
        count: 0,
        success: 0,
        failed: 0,
        click: 0,
      },
    ];
  }

  acc[o.type][0]["count"] = (acc[o.type][0]["count"] || 0) + 1;
  acc[o.type][0][o.name] = acc[o.type][0][o.name] + 1;

  return acc;
}, {});

const result = ob.dataTwo.reduce((acc, o) => {
  acc[o.type][0][o.name] = acc[o.type][0][o.name] + 1;

  return acc;
}, dataOneReduced);

for (const type of Object.keys(result)) {
  const obj = result[type][0];
  obj.successPercentage = obj.success / obj.count * 100;
}

console.info(result);

Вариант 2

Вы можете вставить расчет прямо в .reduce(), и он будет работать нормально, потому что при каждой итерации будет перезаписываться только значение, а на выходе будет только последнее правильное значение.

const ob = {
  "dataOne": [
    {
      "type": "Type 1",
      "name": "failed"
    },
    {
      "type": "Type 1",
      "name": "success"
    },
    {
      "type": "Type 2",
      "name": "success"
    },
    {
      "type": "Type 3",
      "name": "success"
    },
  ],
  "dataTwo": [
    {
      "type": "Type 1",
      "name": "click",
    },
    {
      "type": "Type 2",
      "name": "click",
    },
    {
      "type": "Type 2",
      "name": "click",
    },
    {
      "type": "Type 1",
      "name": "click",
    },
    {
      "type": "Type 3",
      "name": "click",
    },
  ]
};

const dataOneReduced = ob.dataOne.reduce((acc, o) => {
  if (!acc[o.type]) {
    acc[o.type] = [
      {
        count: 0,
        success: 0,
        failed: 0,
        click: 0,
      },
    ];
  }

  acc[o.type][0]["count"] = (acc[o.type][0]["count"] || 0) + 1;
  acc[o.type][0][o.name] = acc[o.type][0][o.name] + 1;
  acc[o.type][0].successPercentage = acc[o.type][0].success / acc[o.type][0].count * 100;

  return acc;
}, {});

const result = ob.dataTwo.reduce((acc, o) => {
  acc[o.type][0][o.name] = acc[o.type][0][o.name] + 1;

  return acc;
}, dataOneReduced);

console.info(result);

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