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

const October = [
  {
    event_category: 'EVENT',
    date: '2022-10-02',
    detail: 'event',
  },
  {
    event_category: 'TASK',
    date: '2022-10-03',
    detail: 'task',
  },
  {
    event_category: 'EVENT',
    date: '2022-10-04',
    detail: 'event 1',
  },
  {
    event_category: 'TASK',
    date: '2022-10-04',
    detail: 'task 1',
  },
  {
    event_category: 'TASK',
    date: '2022-10-04',
    detail: 'task 2',
  },
];

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

результат, который я хочу.

const newOct = [
  {
    '2022-10-02': {
      event_category: 'EVENT',
      date: '2022-10-02',
    },
    '2022-10-03': {
      event_category: 'TASK',
      date: '2022-10-03',
    },
    '2022-10-04': {
      event_category: 'TASK_EVENT',
      date: '2022-10-04',
    },
  },
];

откуда вы берете October массив?

Srushti Shah 16.01.2023 13:11

@SrushtiShah я только что сделал это, например, это действительно имеет значение ..?

mrbig 16.01.2023 13:34

да Если вы выбираете из базы данных, тогда было бы проще

Srushti Shah 16.01.2023 14:07

да, это выборка из API, и у меня есть сотни таких списков, поэтому я сделал это проще. Большое спасибо за ваш ответ. я не знал, чем отличается, если он извлекается из API, так что это будет проще.

mrbig 16.01.2023 18:00

@mrbig ... ОП может взглянуть на два других подхода (оба основаны на reduce и map соответственно forEach по запросу), предоставленные поздним ответом.

Peter Seliger 18.01.2023 14:33
Поведение ключевого слова "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) для оценки ваших знаний,...
3
5
62
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Вы достигаете этого, используя следующий код

const October = [
    {
        event_category: 'EVENT',
        date: '2022-10-02',
        detail: 'event',
    },
    {
        event_category: 'TASK',
        date: '2022-10-03',
        detail: 'task',
    },
    {
        event_category: 'EVENT',
        date: '2022-10-04',
        detail: 'event 1',
    },
    {
        event_category: 'TASK',
        date: '2022-10-04',
        detail: 'task 1',
    },
    {
        event_category: 'TASK',
        date: '2022-10-04',
        detail: 'task 2',
    },
];

function onlyUnique(value, index, self) {
    return self.indexOf(value) === index;
}

let newOct = [{}];
let dates = October.map(item => item.date);
dates = dates.filter(onlyUnique);

for (let date of dates) {
    let event_category = ''; 
    for (let item of October) {
        if (item.date === date) {
            event_category = event_category ? event_category.includes(item.event_category) ? event_category : event_category + "_" + item.event_category : item.event_category;
        }
    }
    newOct[0][date] = { event_category, date };
}
console.info('newOct: ', newOct);

Проблема ОП может быть решена с помощью...

  1. либо двойной подход обоих, простая редукция и простая задача mapping

  2. или одной, но немного более сложной reduce задачей.

Что касается 1)...

  • сначала можно было бы reduce предоставить массив в объект, где ключи являются уникальными date, а event_category упомянутого элемента представляет собой массив, который содержит каждое значение/имя, связанное с датой event_category. Функция редуктора тогда так же проста, как...

    function createAndAggregateDateBasedCategoryList(
      result, { event_category, date }
    ) {
      // - create and/or access the date-based category-item ...
      (result[date] ??= {
        event_category: [],
        date,
      })
      // ... and push the current category-name
      //     into the category-list.
      .event_category
      .push(event_category);
    
      return result;
    }
    
  • во-вторых, в задаче mapping можно объединить каждое окончательное event_category значение из уникальных имен категорий массива. Связанная функция будет выглядеть так...

    function concatUniqueCategoryNames({ event_category, ...rest }) {
      return {
        event_category: [...new Set(event_category)].join('_'),
        ...rest,
      };
    }
    

Окончательное решение реализует/показывает использование двух вышеуказанных функций...

function createAndAggregateDateBasedCategoryList(
  result, { event_category, date }
) {
  // - create and/or access the date-based category-item ...
  (result[date] ??= {
    event_category: [],
    date,
  })
  // ... and push the current category-name
  //     into the category-list.
  .event_category
  .push(event_category);

  return result;
}

function concatUniqueCategoryNames({ event_category, ...rest }) {
  return {
    event_category: [...new Set(event_category)].join('_'),
    ...rest,
  };
}

const October = [{
  event_category: 'EVENT',
  date: '2022-10-02',
  detail: 'event',
}, {
  event_category: 'TASK',
  date: '2022-10-03',
  detail: 'task',
}, {
  event_category: 'EVENT',
  date: '2022-10-04',
  detail: 'event 1',
}, {
  event_category: 'TASK',
  date: '2022-10-04',
  detail: 'task 1',
}, {
  event_category: 'TASK',
  date: '2022-10-04',
  detail: 'task 2',
}];

console.info(
  '+++ step 1 +++\n... collected date-based category-names as `event_category` array ...',
  October
    .reduce(createAndAggregateDateBasedCategoryList, {}),
);
console.info(
  '+++ step 2 +++\n... creating the final result from each of the aggregated category-names ...',
  Object.fromEntries(
    Object
      .entries(
        October.reduce(
          createAndAggregateDateBasedCategoryList, {}
        )
      )
      .map(([key, value]) => [
        key, concatUniqueCategoryNames(value)
      ])
    )
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

Что касается 2)...

Можно было бы объединить обе показанные выше задачи в одну функцию-редуктор, где создание конечного значения event_category происходит только на последнем шаге редукции. Функция редуктора и ее использование затем меняются на...

function createAndAggregateDateBasedCategoryName(
  result, item, idx, arr,
) {
  const { event_category, date } = item;

  // - create and/or access the date based category item.
  const dateBasedItem = (result[date] ??= {
    event_category: [],
    date,
  });
  // - collect the current category-name
  //   within the temporary category-list.
  dateBasedItem
    .event_category
    .push(event_category);

  // - within the last/final reduce step ...
  if (idx >= arr.length - 1) {

    // ... create the final names by concatenating
    //     each temporary list's unique category-names.
    Object
      .values(result)
      .forEach(value =>
        value.event_category = [
          ...new Set(value.event_category)
        ].join('_')
      );
  }
  return result;
}

const October = [{
  event_category: 'EVENT',
  date: '2022-10-02',
  detail: 'event',
}, {
  event_category: 'TASK',
  date: '2022-10-03',
  detail: 'task',
}, {
  event_category: 'EVENT',
  date: '2022-10-04',
  detail: 'event 1',
}, {
  event_category: 'TASK',
  date: '2022-10-04',
  detail: 'task 1',
}, {
  event_category: 'TASK',
  date: '2022-10-04',
  detail: 'task 2',
}];

console.info(
  October
    .reduce(createAndAggregateDateBasedCategoryName, {})
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

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