Как я могу помещать объекты в массивы с похожими именами?

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

например

// базовый объект

  {
    question_10: ""
    question_10a: ""
    question_11_checkbox: false
    question_11_checkbox_copy_0: false
    question_11_checkbox_copy_1: true
    question_11_text: "110 Monroe St"
    question_11_text_copy_0: "186 Aspen Road"
    question_12_checkbox: false
    question_12_checkbox_copy_0: false
    question_12_text: "New York"
    question_12_text_copy_0: "South Orange"
    ...
  }

// то, что я хочу

{
  question_10: ""
  question_10a: ""
  question_11_checkbox: false
  question_11_checkbox_copies: [
    { question_11_checkbox_copy_0: false } 
    { question_11_checkbox_copy_1: true }
  ]
  question_11_text: "101 Monroe St"
  question_11_text_copies: [
    { question_11_text_copy_0: "186 Aspen Road"}
  ]
  question_12_checkbox: false
  question_12_checkbox_copies: [
    { question_12_checkbox_copy_0: false}
  ]
  question_12_text: "New York"
  question_12_text_copies: [
    { question_12_text_copy_0: "South Orange"}
  ]

   ...
 }

До сих пор мне удавалось отфильтровывать копии исходного объекта и создавать массивы для копий.

 // filter out copy keys
const copiesKey = Object.keys(data).filter(key => key.includes('copy'));

const copy = {};

// create arrays for copies
copiesKey.map(copiedQuestion => {

  if (!(`${copiedQuestion.slice(0, copiedQuestion.length - 7)}_copies` in copy)) {
    copy[`${copiedQuestion.slice(0, copiedQuestion.length - 7)}_copies`] = [];
  }
});

Где я застрял, непонятно, как сопоставить объект с соответствующим массивом и нажать его. например

question_11_text_copies: [
  { question_11_text_copy_0: "186 Aspen Road" }
]

До сих пор я пытался нарезать последние три ключа объекта copy_0 и сопоставить ключ с именем массива с помощью array.filter, но это не сработало, как ожидалось.

Как я могу сопоставить объекты «copy_n» с соответствующим массивом и поместить эти объекты в массив?

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
0
42
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете уменьшить записи объекта до нового объекта. Для каждого ключа найдите, есть ли у него базовый ключ (тот, что перед «копировать»), используя RegExp с просмотром вперед. Если у него нет базового ключа, добавьте его непосредственно в аккумулятор. Если это так, добавьте его в соответствующий массив «copies» (при необходимости инициализируйте его с помощью логического нулевого присваивания ??=) (ТС детская площадка).

const fn = obj => Object.entries(obj)
  .reduce((acc, [k, v]) => {
    const [baseKey] = k.match(/.*(?=_copy_)/) ?? [] // get the key from an item with copy
  
    if(!baseKey) acc[k] = v // if no baseKey add the item to the accumulator
    else {
      const copiesKey = `${baseKey}_copies`
      acc[copiesKey] ??= [] // if no copies key add a new one to the accumulator    
      acc[copiesKey].push({ [k]: v }) // create an object and push to the current copies key
    }
    
    return acc
  }, {})

const obj = {"question_10":"","question_10a":"","question_11_checkbox":false,"question_11_checkbox_copy_0":false,"question_11_checkbox_copy_1":true,"question_11_text":"110 Monroe St","question_11_text_copy_0":"186 Aspen Road","question_12_checkbox":false,"question_12_checkbox_copy_0":false,"question_12_text":"New York","question_12_text_copy_0":"South Orange"}
const result = fn(obj)

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

Это может быть немного старомодно, но использование цикла for...in в сочетании с сопоставлением шаблона регулярного выражения с ключом может быть самым очевидным решением.

const data = {
  question_10: "",
  question_10a: "",
  question_11_checkbox: false,
  question_11_checkbox_copy_0: false,
  question_11_checkbox_copy_1: true,
  question_11_text: "110 Monroe St",
  question_11_text_copy_0: "186 Aspen Road",
  question_12_checkbox: false,
  question_12_checkbox_copy_0: false,
  question_12_text: "New York",
  question_12_text_copy_0: "South Orange",
};

const copy_n = /^(.*)_copy_(\d+)$/;
const result = {};
for (const key in data) {
  const value = data[key];
  const match = key.match(copy_n);
  
  if (match) {
    const copies_key = `${match[1]}_copies`;
    const index = parseInt(match[2], 10);
    result[copies_key] ||= [];
    result[copies_key][index] = { [key]: value };
  } else {
    result[key] = value;
  }
}

console.log(result);

Шаблон /^(.*)_copy_(\d+)$/ соответствует всему, что заканчивается на _copy_, за которым следует 1 или более десятичных знаков. Все до _copy_ помещается в группу захвата 1, десятичные знаки после _copy_ помещаются в группу захвата 2.

Если совпадения нет (сценарий еще), мы просто присваиваем значение тому же ключу.

Если есть совпадение (сценарий если), мы сначала определяем ключ коллекции (copies_key) и используемый индекс. Затем мы проверяем, установлено ли уже result[copies_key] (точнее, мы проверяем, является ли это истинным значением). Если это не так, мы присваиваем его пустому массиву. После этого мы используем index, чтобы присвоить объекту правильный индекс в массиве.

Спасибо. Я изменил ваш цикл for in на Object.keys.forEach и использовал camelCase для переменных, но в остальном работает отлично!

London804 23.04.2022 00:18

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