skip to Main Content

Can you help on how to combine data in two different arrays with different structures?

I take data via API, the first request:

[
  {
    "category_id": "12345",
    "category_name": "itemgroup 1",
    "category_is_hidden": "0",
    "product_id": "9999999",
    "product_name": "item 1",
    "product_sku": "0002344",
    "product_brand": null,
    "product_vendor_code": "art 123",
    "is_productset": "0",
    "productset_items": null,
    "is_service": "0",
    "is_serial": "0",
    "variations": {
      "id": "1122334455",
      "name": "red",
      "measurement_unit": "unit_piece",
      "quantity_minimal_piece": "1.000",
      "sku": null,
      "vendor_code": "",
      "retail_price": "2550.00",
      "wholesale_price": "2550.00",
      "discount_type": "percent",
      "discount": "0.00",
      "barcodes": ["2000471000002", "2000481000009"]
    }
  }
]

second request:

[
  {
    "9999999": {
      "company_id": 63,
      "branch_id": 69,
      "variation_id": 954629,
      "supplier_id": 0,
      "quantity": 1
    }
  }
]

I need to match the data by product_id and get the output in the format:
Product Name, Quantity

At the moment I only came up with:

async function getstockandproductinfo() {
  try {
    const stockinforesponse = await axios.get(`${BASE_URL}/stock?branch_id=0`, {
      headers: {'API-KEY': API_KEY}
    });
    const productinforesponse = await axios.get (`${BASE_URL}/products`, {
      headers: {'API-KEY': API_KEY}
    });
    const productdata = productinforesponse.data;
    const stocksdata = stockinforesponse.data;
    const meld = [].concat(productdata, stocksdata);

    meld.forEach(item => {
      if (typeof item === 'object' && item !== null) {
        for (const product_id in item) {
          if (item[product_id] && item[product_id].hasOwnProperty('quantity')) {
            const quantity = item[product_id].quantity;
            console.log(`Product ID: ${product_id}, Quantity: ${quantity}`);
          }
        }
      }
    });

  } catch (error) {
    console.error('Error', error);
  }
}

getstockandproductinfo();

when I try to get the product name I get undefined

I will be glad for any help, as I am a complete noob)

4

Answers


  1. Following is one way to do it:

    // create a hashMap out of obj1 so that Key is product_id and value is the whole object.. this will help us to look up fast
    const obj1ReduceToAMap = obj1.reduce((res, val) => ({...res, [val.product_id]: val}), {});
    
    // iterate over obj2.. 
    obj2.forEach(val => {
      //get all the objects that can be there for each element, and get the corresponding name from obj1ReduceToAMap
      Object.keys(val).forEach(key => console.log("product_id: ", key, "quantity: ", val[key].quantity, "name: ", obj1ReduceToAMap[key].product_name));
    });
    
    Login or Signup to reply.
  2. this will do

     async function getstockandproductinfo() {
         try {
         const productdata = productinforesponse.data;
         const stocksdata = stockinforesponse.data;
         const stocksObj = stocksdata.reduce((res,val) => {
           const key = Object.keys(val)[0];
          return { ...res, [key]: val[key] }
        },{});
        
        const combinedArray = productdata.reduce((result, product) => {
          const matchingObj = stocksObj[product.product_id]
          if (matchingObj) {      
           result.push({ product_name: product.product_name , quantity: matchingObj.quantity });
          }
          return result;
        }, []);
        console.log("combined array: ", combinedArray)
    
      } catch (error) {
        console.error('Error', error);
      }
        }
    
    Login or Signup to reply.
  3. You can loop the second array, find the key of each element, search for it in the first array via filter() and if found, copy the values at the appropriate keys via a loop:

    let firstArray = [
      {
        "category_id": "12345",
        "category_name": "itemgroup 1",
        "category_is_hidden": "0",
        "product_id": "9999999",
        "product_name": "item 1",
        "product_sku": "0002344",
        "product_brand": null,
        "product_vendor_code": "art 123",
        "is_productset": "0",
        "productset_items": null,
        "is_service": "0",
        "is_serial": "0",
        "variations": {
          "id": "1122334455",
          "name": "red",
          "measurement_unit": "unit_piece",
          "quantity_minimal_piece": "1.000",
          "sku": null,
          "vendor_code": "",
          "retail_price": "2550.00",
          "wholesale_price": "2550.00",
          "discount_type": "percent",
          "discount": "0.00",
          "barcodes": ["2000471000002", "2000481000009"]
        }
      }
    ];
    
    let secondArray = [
      {
        "9999999": {
          "company_id": 63,
          "branch_id": 69,
          "variation_id": 954629,
          "supplier_id": 0,
          "quantity": 1
        }
      }
    ];
    
    for (let product of secondArray) {
        let product_id = Object.keys(product)[0];
        let found = firstArray.filter(item => item.product_id === product_id);
        let index = firstArray.indexOf(found[0]);
        if (index >= 0) {
            for (let key in product[product_id]) {
                firstArray[index][key] = product[product_id][key];
            }
        }
    }
    
    console.log(firstArray);
    Login or Signup to reply.
  4. If I understood correctly, you want to combine datasets that relate to the same product. Since I do not know what you want to do with the result later, here are two solutions that result in different data structures, each better suited for different uses after the combination.

    The following combines into an Array:

    const DATA_REQUEST_A = [
      {
        "category_id": "12345",
        "category_name": "itemgroup 1",
        "category_is_hidden": "0",
        "product_id": "9999999",
        "product_name": "item 1",
        "product_sku": "0002344",
        "product_brand": null,
        "product_vendor_code": "art 123",
        "is_productset": "0",
        "productset_items": null,
        "is_service": "0",
        "is_serial": "0",
        "variations": {
          "id": "1122334455",
          "name": "red",
          "measurement_unit": "unit_piece",
          "quantity_minimal_piece": "1.000",
          "sku": null,
          "vendor_code": "",
          "retail_price": "2550.00",
          "wholesale_price": "2550.00",
          "discount_type": "percent",
          "discount": "0.00",
          "barcodes": ["2000471000002", "2000481000009"]
        }
      }
    ];
    
    const DATA_REQUEST_B = [
      {
        "9999999": {
          "company_id": 63,
          "branch_id": 69,
          "variation_id": 954629,
          "supplier_id": 0,
          "quantity": 1
        }
      }
    ];
    
    function merge(...objs) {
      return Object.assign({}, ...objs);
    }
    
    function combineByKey(dataA, dataB, keyA) {
      return dataA.reduce(
        (results, itemA) => {
          const matchBy = itemA[keyA];
          if (matchBy) {
            return dataB.reduce(
              (_results, itemB) => {
                const match = itemB[matchBy];
                if (match != null) {
                  return _results.concat(merge(itemA, match));
                }
                return _results;
              },
              results
            );
          }
          return results;
        },
        []
      );
    }
    
    console.log(combineByKey(DATA_REQUEST_A, DATA_REQUEST_B, 'product_id'));

    This gives an Array of related products combined which will make it easy to loop over it. If you need a specific product, you have to look for it by employing .filter/.find.

    const combinations = combineByKey(DATA_REQUEST_A, DATA_REQUEST_B, 'product_id');
    combinations.forEach(product => {
      console.log(product);
    });
    

    You could instead combine into an Object (or a Map) instead of an Array to make lookups faster if you only want to get (a) specific product(s) later:

    const DATA_REQUEST_A = [
      {
        "category_id": "12345",
        "category_name": "itemgroup 1",
        "category_is_hidden": "0",
        "product_id": "9999999",
        "product_name": "item 1",
        "product_sku": "0002344",
        "product_brand": null,
        "product_vendor_code": "art 123",
        "is_productset": "0",
        "productset_items": null,
        "is_service": "0",
        "is_serial": "0",
        "variations": {
          "id": "1122334455",
          "name": "red",
          "measurement_unit": "unit_piece",
          "quantity_minimal_piece": "1.000",
          "sku": null,
          "vendor_code": "",
          "retail_price": "2550.00",
          "wholesale_price": "2550.00",
          "discount_type": "percent",
          "discount": "0.00",
          "barcodes": ["2000471000002", "2000481000009"]
        }
      }
    ];
    
    const DATA_REQUEST_B = [
      {
        "9999999": {
          "company_id": 63,
          "branch_id": 69,
          "variation_id": 954629,
          "supplier_id": 0,
          "quantity": 1
        }
      }
    ];
    
    function merge(...objs) {
      return Object.assign({}, ...objs);
    }
    
    function combineByKey(dataA, dataB, keyA) {
      return dataA.reduce(
        (results, itemA) => {
          const matchBy = itemA[keyA];
          if (matchBy) {
            return dataB.reduce(
              (_results, itemB) => {
                const match = itemB[matchBy];
                if (match != null) {
                  return Object.assign(_results, {
                    [matchBy]: merge(itemA, match)
                  });
                }
                return _results;
              },
              results
            );
          }
          return results;
        },
        {} // <-- Using an object literal here
      );
    }
    
    console.log(combineByKey(DATA_REQUEST_A, DATA_REQUEST_B, 'product_id'));

    This would enable you to look for products by the value of their product_id:

    const combinations = combineByKey(DATA_REQUEST_A, DATA_REQUEST_B, 'product_id');
    console.log(combinations[9999999]);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search