Как объединить два массива объектов на основе одного и того же ключа и значения в javascript?

#javascript #arrays

#javascript #массивы

Вопрос:

У меня есть два массива videos и storeProducts. массив видео может иметь product_id, а storeProducts должен иметь product_id. Мне нужно объединить их на основе обоих produt_id, иначе в массив будут помещены только элементы видео.

      let videos = [
      {
        "id": 1,
        "product_id":"training_video_test_1",
        "video_title": "Video title 1",
        "video_short_description": "desc 1"
      },
      {
        "id": 2,
        "product_id":"training_video_test_2",
        "video_title": "Video title 2",
        "video_short_description": "desc 2"
      },
      {
        "id": 3,
        "product_id":"training_video_test_3",
        "video_title": "Video title 3",
        "video_short_description": "desc 3"
      }
     
  ];
  
  let storeProducts = [
      {
          "product_id":"training_video_test_1",
          "prduct_title":"training_video_test_1",
          "price":100
      },
      {
        "product_id":"training_video_test_2",
        "prduct_title":"training_video_test_2",
        "price":100
    }
  ];
  

Мне нужно объединить эти два, когда storeProducts.product_id === videos.product_id в противном случае игнорируются элементы товаров магазина, которые нажимают только элементы видео.

Пример вывода:

 [
      {
        "id": 1,
        "product_id":"training_video_test_1",
        "video_title": "Video title 1",
        "video_short_description": "desc 1",
        "prduct_title":"training_video_test_1",
        "price":100
      },
      {
        "id": 2,
        "product_id":"training_video_test_2",
        "video_title": "Video title 2",
        "video_short_description": "desc 2",
        "prduct_title":"training_video_test_2",
        "price":100
      },
      {
        "id": 3,
        "product_id":"training_video_test_3",
        "video_title": "Video title 3",
        "video_short_description": "desc 3"
      }
  ]
  

Я пробовал так:

 let resultArr = [];
videos.forEach((v)=>{
  storeProducts.forEach((p)=>{
  if(p.product_id == v.product_id){
      resultArr.push(Object.assign({},v,p))
    
    }
  })
})
  

Но это работает не так, как я ожидал.Пожалуйста, помогите мне.

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

1. Что вы делаете, когда product_id не совпадает? Также рассмотрите возможность использования === для сравнения, а не ==

2. если мне это нравится: let resultArr = []; videos.forEach((v)=>{ storeProducts.forEach((p)=>{ if(p.product_id === v.product_id){ resultArr.push(Object.assign({},v,p)) }else{ resultArr.push(Object.assign({},p)) } }) }) Это дублирует.

Ответ №1:

Вместо этого вы можете использовать map

 let videos = [
    { id: 1, product_id: "training_video_test_1", video_title: "Video title 1", video_short_description: "desc 1" },
    { id: 2, product_id: "training_video_test_2", video_title: "Video title 2", video_short_description: "desc 2" },
    { id: 3, product_id: "training_video_test_3", video_title: "Video title 3", video_short_description: "desc 3" },
];

let storeProducts = [
    { product_id: "training_video_test_1", prduct_title: "training_video_test_1", price: 100 },
    { product_id: "training_video_test_2", prduct_title: "training_video_test_2", price: 100 },
];

const result = videos.map(v => ({ ...v, ...storeProducts.find(sp => sp.product_id === v.product_id) }));

console.log(result);  

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

1. Ты потрясающий. Это работает. Можете ли вы предложить несколько расширенных руководств по работе с массивами в javascript?. В основном я использую for и forEach.

2. @Hari Попробуйте ознакомиться с методами работы с массивами в ES5

3. Это хороший вариант. Для меня это работает идеально. Большое вам спасибо.

Ответ №2:

Используйте оператор распространения.

 let resultArr = [];
videos.forEach((v)=>{
    storeProducts.forEach((p)=>{
        if(p.product_id == v.product_id){
            resultArr.push({...v, ...p})

        }
    })
})
  

Ответ №3:

Я рекомендую вам избегать оператора find и распространения для каждого элемента в обработчике (очень низкая производительность), вы можете преобразовать storeProducts массив в объект ключ-значение, который обеспечивает более быстрый способ доступа к объектам.

 let videos = [    {      "id": 1,      "product_id":"training_video_test_1",      "video_title": "Video title 1",      "video_short_description": "desc 1"    },    {      "id": 2,      "product_id":"training_video_test_2",      "video_title": "Video title 2",      "video_short_description": "desc 2"    },    {      "id": 3,      "product_id":"training_video_test_3",      "video_title": "Video title 3",      "video_short_description": "desc 3"    }],
    storeProducts = [    {      "product_id":"training_video_test_1",      "prduct_title":"training_video_test_1",      "price":100    },    {      "product_id":"training_video_test_2",      "prduct_title":"training_video_test_2",      "price":100  }],
    mapped = storeProducts.reduce((a, c) => (a[c.product_id] = c, a), {}),
    result = videos.map(o => Object.assign(o, mapped[o.product_id]));

console.log(result);  
 .as-console-wrapper { max-height: 100% !important; top: 0; }