skip to Main Content

I have two arrays
Array1

{"Colour":"RASPBERRY","Size":"11"}

and a list of products

Array2
[
  {
    "ProductID": 33043,
    "Key": "Colour",
    "Value": "RASPBERRY"
  },
  {
    "ProductID": 33043,
    "Key": "Size",
    "Value": "4"
  },
  {
    "ProductID": 33044,
    "Key": "Colour",
    "Value": "RASPBERRY"
  },
  {
    "ProductID": 33044,
    "Key": "Size",
    "Value": "5"
  },
  {
    "ProductID": 33045,
    "Key": "Colour",
    "Value": "RASPBERRY"
  },
  {
    "ProductID": 33045,
    "Key": "Size",
    "Value": "6"
  },
  {
    "ProductID": 33046,
    "Key": "Colour",
    "Value": "RASPBERRY"
  },
  {
    "ProductID": 33046,
    "Key": "Size",
    "Value": "7"
  },
  {
    "ProductID": 33047,
    "Key": "Colour",
    "Value": "RASPBERRY"
  },
  {
    "ProductID": 33047,
    "Key": "Size",
    "Value": "8"
  }
]

I have both those arrays, I need to fetch ProductID from Array2 Using the data from Array 1, the list can be thousands long, want to avoid heavy work

Below is my attempt:

 // Step 1: Group entries in array2 by ProductID
        var productDict = {};

        $.each(array2, function(index, entry) {
            var productID = entry.ProductID;
            var key = entry.Key;
            var value = entry.Value;

            if (!productDict[productID]) {
                productDict[productID] = {};
            }
            productDict[productID][key] = value;
        });

        // Step 2: Check each ProductID group against the criteria in array1
        var matchingProductIDs = [];

        $.each(productDict, function(productID, attributes) {
            var match = true;
            $.each(array1, function(key, value) {
                if (attributes[key] !== value) {
                    match = false;
                    return false; // Break out of the loop
                }
            });
            if (match) {
                matchingProductIDs.push(productID);
            }
        });

        // Output the result
        console.log("Matching Product IDs:", matchingProductIDs);
    

the above code works, but it seems heavy and would like a better solution, if anyone can help.

2

Answers


  1. In your PHP, Consider using SQL like so:

    SELECT DISTINCT ProductID 
    FROM Products 
    WHERE (`Key`='Colour' AND `Value`='RASPBERRY')
    AND ProductID IN (SELECT ProductID FROM Products WHERE `Key`='size' AND `Value`='11');
    

    Test results here: https://sqlfiddle.com/mysql/online-compiler?id=f39030b7-5eaa-49bf-b873-ad9f6d3a8ab1

    To use the values you have from jQuery, they need to be sent to the PHP. So you will need to have a PHP Script that accepts the passed data and uses it in the SQL Query. It can also return the results back as JSON.

    <?php
    $myKeys = array();
    $myVals = array();
    $results = array();
    
    foreach($_GET['filter'] as $k => $v){
      $myKeys += $k;
      $myVals += $v;
    }
    
    $mysqli = new mysqli("localhost","my_user","my_password","my_db");
    
    $query = "SELECT DISTINCT ProductID FROM Products WHERE (`Key`='?' AND `Value`='?')
    AND ProductID IN (SELECT ProductID FROM Products WHERE `Key`='?' AND `Value`='?');"
    
    $stmt = $mysqli->prepare($query);
    $stmt->bind_param("ssss", $myKeys[0], $myVals[0], $myKeys[1], $myVals[1]);
    $stmt->execute();
    $result = $stmt->get_result();
    while ($row = $result->fetch_assoc()) {
         $results += $row['ProductId'];
    }
    $mysqli -> close();
    
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode($results);
    ?>
    

    In your jQuery, you can use something like:

    var myData = {"filter": {"Colour":"RASPBERRY","Size":"11"}};
    $.getJSON('localhost/queryProducts.php', myData, function(results){
      // Do something with results
    });
    
    Login or Signup to reply.
  2. Preferably, the data should be transformed into a searchable format on the back-end.
    If that is not and option, data can be transformed on the front-end :

    const data = [ { "ProductID": 33043, "Key": "Colour", "Value": "RASPBERRY" },
                   { "ProductID": 33043, "Key": "Size",   "Value": "4" },
                   { "ProductID": 33044, "Key": "Colour", "Value": "RASPBERRY" },
                   { "ProductID": 33044, "Key": "Size",   "Value": "5" },
                   { "ProductID": 33045, "Key": "Colour", "Value": "RASPBERRY" },
                   { "ProductID": 33045, "Key": "Size",   "Value": "6" },
                   { "ProductID": 33046, "Key": "Colour", "Value": "RASPBERRY" },
                   { "ProductID": 33046, "Key": "Size",   "Value": "7" },
                   { "ProductID": 33047, "Key": "Colour", "Value": "RASPBERRY" },
                   { "ProductID": 33047, "Key": "Size",   "Value": "8" } ];
    
    // transform data into searchable format
    const products = Object.values( Object.groupBy(data, o => o.ProductID) )
        .map(a => Object.assign( ...a.map(o => ({ ProductID: o.ProductID, [o.Key]: o.Value })) ));
    
    console.log( JSON.stringify( products ).replace(/,{/g, ',n {') );
    
    // find the product
    const search = { "Colour": "RASPBERRY", "Size": "7" };
    
    const product = products.find(p => Object.entries(search).every(([k, v]) => p[k] === v));
    
    console.log( product );
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search