объединение аналогичной пары ключ/значение в массив

#javascript

Вопрос:

Мне интересно, могу ли я объединить несколько объектов на основе заданного идентификатора в массив объекта? Надеюсь, я смогу объяснить это лучше ниже:

пытаюсь, чтобы вывод каждого элемента индекса коллекции был таким:

 [
  {
    brand: 'Porsche',
    model: ['Cayenne', 'Macan'],
    id: 1
  },
  {
    brand: 'BMW',
    model: ['M4','M3'],
    id: 3
  }
]
 

Но приведенный ниже код дублирует id:1 автомобиль марки Porsche в carCollection :

 [
  {
    brand: 'Porsche',
    model: ['Cayenne'],
    id: 1,
  },
  {
    brand: 'Porsche',
    model: ['Macan'],
    id: 1
  }
]
 
 let cars = {
    brands: [ {name:'Porsche', id:1}, {name:'Mercedes-Benz', id:2},{name:'BMW', id:3},],
    models: [  {name:'Cayenne', id:1}, {name:'C45', id:2}, {name:'M4', id:3}, {name:'M3', id:3}, {name:'Macan', id:1}]
}

// empty array
let carCollection = []

let { brands, models } = cars;


function carMatcher(brands, models){

    for(let brand of brands){
 
        for(let model of models){
            const carObject = {
                brand: '',
                model: [],
                id: 0
            }

           if(model.id === brand.id){
                    carObject.brand = brand.name
                    carObject.model.push(model.name)
                    carObject.id = brand.id
                    carCollection.push(carObject)
                
            } 
        }

    } 

}

carMatcher(brands, models)

 

Комментарии:

1. А что, если есть две машины одной марки, но с разными идентификаторами или наоборот? Или это невозможно?

2. я тоже хотел бы знать, ха-ха. это вызов для меня и, безусловно, случай, о котором стоит написать, НО… я бы подумал, что другой идентификатор будет человеческой ошибкой при вводе в базу данных FZs

Ответ №1:

Вы можете легко достичь этого результата с помощью Map и forEach

 let cars = {
  brands: [
    { name: "Porsche", id: 1 },
    { name: "Mercedes-Benz", id: 2 },
    { name: "BMW", id: 3 },
  ],
  models: [
    { name: "Cayenne", id: 1 },
    { name: "C45", id: 2 },
    { name: "M4", id: 3 },
    { name: "M3", id: 3 },
    { name: "Macan", id: 1 },
  ],
};

const dict = new Map();

cars.brands.forEach(({ name, id }) => {
  dict.set(id, { brand: name, id, model: [] });
});

cars.models.forEach(({ name, id }) => {
  if (dict.has(id)) dict.get(id).model.push(name);
});

const result = [...dict.values()];
console.log(result); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

ИЗМЕНИТЬ: Более простая версия

 let cars = {
  brands: [
    { name: "Porsche", id: 1 },
    { name: "Mercedes-Benz", id: 2 },
    { name: "BMW", id: 3 },
  ],
  models: [
    { name: "Cayenne", id: 1 },
    { name: "C45", id: 2 },
    { name: "M4", id: 3 },
    { name: "M3", id: 3 },
    { name: "Macan", id: 1 },
  ],
};

let dict = {},
  result = [];

for (let val of cars.brands) {
  dict[val.id] = {
    brand: val.name,
    id: val.id,
    model: [],
  };
}

for (let val of cars.models) {
  const id = val.id;
  const name = val.name;

  const objInDict = dict[id];
  if (objInDict) {
    objInDict.model.push(name);
  }
}

for (let key in dict) {
  result.push(dict[key]);
}

console.log(result); 

Простейший

 let cars = {
  brands: [
    { name: "Porsche", id: 1 },
    { name: "Mercedes-Benz", id: 2 },
    { name: "BMW", id: 3 },
  ],
  models: [
    { name: "Cayenne", id: 1 },
    { name: "C45", id: 2 },
    { name: "M4", id: 3 },
    { name: "M3", id: 3 },
    { name: "Macan", id: 1 },
  ],
};

let result = [];
const { brands, models } = cars;

for (let brand of brands) {
  const { name, id } = brand;
  const newObj = { brand: name, id, model: [] };

  for (let model of models) {
    const { name, id } = model;
    if (newObj.id === id) {
      newObj.model.push(name);
    }
  }

  result.push(newObj);
}

console.log(result); 

Комментарии:

1. интересно! Спасибо, декпк. Если бы я придерживался своего «старомодного» способа, было бы это все еще возможно? Я предполагаю, что мои нынешние знания тусклы =[ . Я думаю, что я сделал этот проект скорее вызовом для себя, а не в такой степени конечным продуктом.

2. @JasonTodd Я добавил простую версию. Надеюсь, это то, что вам нужно. Если это не так, пожалуйста, не стесняйтесь комментировать то, что в коде не так ясно для вас. Рад помочь.

3. @JasonTodd Я добавил две версии. Я думаю, что последнее — это то, что вам нужно.

4. ты буквально потрясающая!!! Большое вам спасибо — люблю видеть много способов подойти к этому.. один из моих инструкторов в bootcamp говорит, что существует почти неограниченное количество способов подойти, и вы только что показали отличный пример этого, ха-ха