Javascript: сопоставить значения двух массивов в новом массиве

У меня есть два массива объектов, которые выглядят так:

const data = [
  {
    id: 1,
    condition: 1,
    helpers: [{id: 1, condition: null}, {id: 2, condition: 2}]
  },
  {
    id: 2,
    condition: null,
    helpers: [{id: 1, condition: 1}, {id: 2, condition: null}]
  }
]

const conds = [
  {
    id: 1,
    conditions: {
       rules: ['test', 'foo']
    }
  },
  {
    id: 2,
    conditions: {
       rules: ['#hashtag', 'foo']
    }
  }
]

Я пытаюсь достичь того, что хочу заменить значения condition в массиве data на значения в массиве conds.

Мое решение, которое работает не очень хорошо, выглядит так:

let newArray = [];

data.forEach(obj => {
        conds.forEach(cond => {
            if (obj.condition) {
                if (obj.condition === cond.id) {
                    obj.condition = cond.conditions.rules;
                    newArray.push(obj);
                }
            } else {
                obj.helpers.forEach(h => {
                    if (h.condition && h.condition === cond.id) {
                        h.condition = cond.conditions.rules;
                        newArray.push(obj);
                    }
                });
            }
        })
    });

Я чувствую, что я довольно близок к решению, поскольку мой newArray содержит свойства изменений, но не для последнего элемента внутри помощников, тогда как свойство condition по-прежнему равно 2.

Результат должен выглядеть так:

[
  {
     id: 1
     condition: ['test', 'foo'],
     helpers: [{id: 1, condition: null}, {id: 2, condition: ['#hashtag', 'foo']}]
  },
  {
     id: 2
     condition: null,
     helpers: [{id: 1, condition: ['test', 'foo']}, {id: 2, condition: null}]
  },
]

Что мне здесь не хватает?

Какой ожидаемый формат вывода?

Eddie 26.10.2018 16:50

Это очень похоже на stackoverflow.com/q/46849286/215552. Вам просто нужно перебрать data, получить helpers и выполнить слияние, описанное в ответах на вопрос, на который я указал.

Heretic Monkey 26.10.2018 16:56

@Eddie я добавил вывод в основной вопрос.

wasddd_ 26.10.2018 17:12
Поведение ключевого слова "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
3
6 969
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Прокрутите массив data, используя forEach, получите id, затем отфильтруйте массив conds с его помощью, используя find(), чтобы получить связанный conditions.rules, например:

data.forEach(function(item) {
    item.condition = conds.find(x => x.id === item.id).conditions.rules;
});

Рабочая рабочий пример:

const data = [{
    id: 1,
    condition: 1,
    helpers: [{id: 1, condition: null}, {id: 2, condition: 2}]
  },{
    id: 2,
    condition: null,
    helpers: [{id: 1, condition: 1}, {id: 2, condition: null}]
}];

const conds = [{
    id: 1,
    conditions: {
       rules: ['test', 'foo']
    }
  },{
    id: 2,
    conditions: {
       rules: ['#hashtag', 'foo']
    }
}];

data.forEach(function(item) {
  item.condition = conds.find(x => x.id === item.id).conditions.rules;
});

console.info(data);

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

Bruno João 26.10.2018 17:09

эй @zakaria, к сожалению, это не рабочий пример. Условия внутри массива helpers также должны быть сопоставлены с условиями.

wasddd_ 26.10.2018 20:34

const data = [
  {
    id: 1,
    condition: 1,
    helpers: [{id: 1, condition: null}, {id: 2, condition: 2}]
  },
  {
    id: 2,
    condition: null,
    helpers: [{id: 1, condition: 1}, {id: 2, condition: null}]
  }
]

const conds = [
  {
    id: 1,
    conditions: {
       rules: ['test', 'foo']
    }
  },
  {
    id: 2,
    conditions: {
       rules: ['#hashtag', 'foo']
    }
  }
]

// START SOLUTION

const rulesMap = conds.reduce((map, condition) => {
    map[condition.id] = condition.conditions.rules;
    return map;
}, {});

const finalData = data.map(dataItem => {
    dataItem.condition = dataItem.condition ? rulesMap[dataItem.condition] : null;
    return dataItem;
});

// END SOLUTION

console.info(finalData);

Создайте карту условий:

const rulesMap = conds.reduce((map, condition) => {
    map[condition.id] = condition.conditions.rules;
    return map;
}, {});

Получить новый список данных с замененными правилами условий:

const finalData = data.map(dataItem => {
    dataItem.condition = dataItem.condition ? rulesMap[dataItem.condition] : null;
    return dataItem;
});

Я получаю ошибку reduction is not defined в этом: /

wasddd_ 26.10.2018 17:10

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

Bruno João 26.10.2018 17:14

Привет, @Bruno - это, к сожалению, не то решение, которого я ожидал. Пожалуйста, посмотрите ожидаемый результат в моем вопросе - на самом деле ваше решение возвращает то же, что и моя версия. : / Условие внутри массива helpers также должно быть сопоставлено с условиями.

wasddd_ 26.10.2018 20:32

Работает с этой логикой, используя вашу карту правил: const finalData = data.map(dataItem => { dataItem.condition = dataItem.condition ? rulesMap[dataItem.condition] : null; dataItem.helpers.map(item => { item.condition = item.condition ? rulesMap[item.condition] : null }) return dataItem; });

wasddd_ 27.10.2018 18:31
Ответ принят как подходящий

Получил работу:

const finalData = data.map(dataItem => {
  dataItem.condition = dataItem.condition ? rulesMap[dataItem.condition] : null;
  dataItem.helpers.map(item => {
    item.condition = item.condition ? rulesMap[item.condition] : null
  })
  return dataItem;
});

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