How to remove duplicate array values and...?

I have this multidimensional array:

//Product//Price//quantity//


$product = array( array("tv", 125 , 11),
                  array("potato", 75 , 25),
                  array("pc", 115 , 7),
                  array("tv", 125 , 4) 
                  )

I need to remove the duplicate data from this array, to insert it into a database.
You can see that there are 2 duplicate products, tv.
I need to remove the duplicates from the array, but I also want the quantity columns to be summed.

Like this:


$product = array( array("tv", 125 , 15),
                  array("potato", 75 , 25),
                  array("pc", 115 , 7)
                  )

I found that there is an array method array_unique(),
it removes the duplicate but I need the quntity columns to be added.
It is highly possible that there is something like this already made, so I ask.

Thank you.


function sanitize_deep($array) {
  foreach($array as $k=>$v) {
     if (is_array($v)) {
       $array[$k] = sanitize_deep($v);
     } else {
        $array[$k] = mysql_real_escape_string($v);
     }
  }
  return $array;
}

Should do the trick. It’s a recursive function that can take up as many dimensions as you like (i.e., unlimited) :slight_smile:

For displaying data you can start as simple as using the strip_tags, htmlentities, and/or several regex (preg_match, preg_replace) functions, or go all out and use something like HTMLPurifier :slight_smile:

Thanks for the replies, I used the database method, but with a for loop.
Sorry, for the double post I accidentaly made.

Is there a method I could sanitize a multidimensional array?
I think I could use what ScallioXTX supposed:
(However It creates an new array then, or I could modify it)


foreach($products as $product) {
  $product = array_map('mysql_real_escape_string', $product);
...

Also, the mysql_real_escape_string indicates MySQL database,
what sanitizing methods should I use for displaying data in HTML?
I guess there shouldn’t be much difference but there could be subtleties.

I would advise against such blanket treatment of data. Sanitizing functions like this push the sanitization higher up the chain (generally) and make no effort to do anything other than the most rudimentary escaping.

Which database engine ?

In MySQL, you could just insert all of the entries, and use an ON DUPLICATE KEY clause to do the work.

Assuming “Product” is a unique key.

INSERT INTO table (Product, Price, Quantity)
VALUES ( ... )
ON DUPLICATE KEY UPDATE Quantity = Quantity + VALUES(Quantity);

Painfully…just use “array_values” once the foreach is done.

Thanks,

how could I do this without setting the product name as array position index?

Nothing premade…


<?php

$products = array( array( "tv", 125, 11 ), array( "pc", 115, 7 ), array( "tv", 125, 4 ) );
$new_products = array();

foreach ( $products as $product ) {
  $key = strtolower( $product[0] );

  if ( isset( $new_products[ $key ] ) ) {
    $new_products[ $key ][2] += $product[2];
    continue;
  }

  $new_products[ $key ] = $product;
}

var_dump( $new_products );

Thanks,

how could I do this without setting the product name as array position index
or go trough the array without using for loop and index $i?

Further to logic_earth’s example, assuming you cannot take the MySQL approach (why?), you could use a helper array to keep track of whether the product has been seen in the loop or not and act accordingly.


$products = array( array( "tv", 125, 11 ), array( "pc", 115, 7 ), array( "tv", 125, 4 ) );
$new_products = array();

$seen = array();
foreach ($products as $product) {
    list($prod,,$quantity) = $product;
    // New product, keep track of it
    if (!isset($seen[$prod])) {
        $seen[$prod]    = count($new_products);
        $new_products[] = $product;
    // We've seen this product before, bump the quantity
    } else {
        $new_products[$seen[$prod]][2] += $quantity;
    }
}
var_dump($new_products);

Ah, My bad.
Anyways, thanks.


$db = mysql_connect(...7);
function sanitize_deep($array) {
  foreach($array as $k=>$v) {
     if (is_array($v)) {
       $array[$k] = sanitize_deep($v);
     } else {
        $array[$k] = mysql_real_escape_string($v);
     }
  }
  return $array;
} 

$product = array( array("tv", 125 , 11),
                  array("potato", 75 , 25),
                  array("pc", 115 , 7),
                  array("tv", 125 , 4) 
                  );

var_dump(sanitize_deep($product));

Output:


array(4) {
  [0]=>
  array(3) {
    [0]=>
    string(2) "tv"
    [1]=>
    string(3) "125"
    [2]=>
    string(2) "11"
  }
  [1]=>
  array(3) {
    [0]=>
    string(6) "potato"
    [1]=>
    string(2) "75"
    [2]=>
    string(2) "25"
  }
  [2]=>
  array(3) {
    [0]=>
    string(2) "pc"
    [1]=>
    string(3) "115"
    [2]=>
    string(1) "7"
  }
  [3]=>
  array(3) {
    [0]=>
    string(2) "tv"
    [1]=>
    string(3) "125"
    [2]=>
    string(1) "4"
  }
}

So, it works perfectly for me :slight_smile:

Remember that mysql_real_escape_string only works if there is a MySQL connection available.

Thank you for the tips.

I tried your method, but it returns me a empty array, what could be the problem?
I’m not good yet at debugging techniques, is there a good software for this?

to elaborate on what joebert said:


$products = array(
  array("tv", 125 , 11),
  array("potato", 75 , 25),
  array("pc", 115 , 7),
  array("tv", 125 , 4) 
);
$db = mysql_connect(...);
foreach($products as $product)
{
  // sanitize data
  $product = array_map('mysql_real_escape_string', $product);
  mysql_query(
'INSERT INTO table (Product, Price, Quantity)
VALUES ("'.$row[0].'", "'.$row[1].'", "'.$row[2].'")
ON DUPLICATE KEY UPDATE Quantity = Quantity + VALUES(Quantity);',$db);
}

Assuming the Product (or Product and Price together) column is the PRIMARY KEY.