Создайте вложенный объект из простого массива

Я пытаюсь создать глубоко вложенный объект JS из простого массива. Сложность заключается в том, что следующий элемент массива всегда должен добавляться к предыдущему.

Предполагая, что мой массив выглядит так:

const filters = [
    [
        {brand: {eq: 'BMW'}},
        {brand: {eq: 'AUDI'}}
    ],
    [
        {year: {eq: '2019'}},
        {year: {eq: '2020'}}
    ],
    [
        {country: {eq: 'CH'}},
        {country: {eq: 'DE'}}
    ]
]

Как я могу получить объект с этой структурой?

    query: {
      and: {
        or: [
          { brand: { eq: 'BMW' } },
          { brand: { eq: 'AUDI' } }
        ],
        and: {
          or: [
            { year: { eq: '2019' } },
            { year: { eq: '2020' } }
          ],
          and: {
            or: [
              { country: { eq: 'CH' } },
              { country: { eq: 'DE' } }
            ],
            ... and so on
          }
        }
      }
    },

Как мне добиться добавления нового блока «или» к предыдущему блоку «или»?

Поведение ключевого слова "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) для оценки ваших знаний,...
1
0
64
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Вы можете создать вложенную структуру по мере прохождения массива. Для каждого элемента добавьте вложенный объект с ключом or, который ссылается на элемент, и каждая последующая итерация работает с предыдущим элементом.

const filters = [
    [
        {brand: {eq: 'BMW'}},
        {brand: {eq: 'AUDI'}}
    ],
    [
        {year: {eq: '2019'}},
        {year: {eq: '2020'}}
    ],
    [
        {country: {eq: 'CH'}},
        {country: {eq: 'DE'}}
    ]
]

const query = {};
let current = query;

for (const filter of filters) {
  current.and = { or: filter };
  current = current.and; 
}

console.info(query);

Иногда ничто не сравнится со старым добрым for циклом.

sp00m 11.12.2020 17:12

Кстати, версия reduce не ужасна, но я считаю ее совершенно ненужной: query = {}; filters.reduce((current, filter) => { current.and = { or: filter }; return current.and}, query)

VLAZ 11.12.2020 17:14

@ sp00m Меня не очень беспокоит хакерство. Меня больше всего беспокоит, что reduce в основном цикл, так как результат игнорируется. Мы также можем сократить for..of аналогичным образом: for (const or of filters) current = current.and = { or } Хотя, я думаю, reduce можно больше играть в гольф.

VLAZ 11.12.2020 17:21

Только для reduce вызова:

const filters = [
    [
        {brand: {eq: 'BMW'}},
        {brand: {eq: 'AUDI'}}
    ],
    [
        {year: {eq: '2019'}},
        {year: {eq: '2020'}}
    ],
    [
        {country: {eq: 'CH'}},
        {country: {eq: 'DE'}}
    ]
];

const query = {};
filters.reduce((x, or) => x.and = { or }, query);

console.info(query);

Хаки, как черт, однако:

  • reduce с побочными эффектами
  • возвращает задание

Подход ВЛАЗа - это путь.

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

VLAZ 11.12.2020 17:24

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