What i want is:
Array-one (the product db array):
Product id
Cat name
Array-two (the category db array):
cat id
Cat name
if Array-one: cat name is equal to Array-two: cat name add all product ids under the cat id
//this foreach is loop to products
foreach($objects as $object) {
//get cat name from product db
$cat_name_product = $object['values']['17'];
// this foreach is loop to cat db
foreach($cat_db as $cat_object) {
// get cat name from cat db
$cat_name_cat_table = $cat_object['values'][2];
// if cat from product DB is equal to cat name from cat DB
if($cat_name_product == $cat_name_cat_table){
$cat_name_product_id = $object['id'];
$cat_name_db_id = $cat_object['id'];
// Add products ids to a specfic row id from cat
$cat_db_row[$cat_name_db_id][] = $cat_name_product_id;
}
}
}
Result array:
Array
(
[45156381272] => Array
(
[0] => 44990952854
)
[45002415686] => Array
(
[0] => 45054787942
[1] => 45056971448
[2] => 45049917079
[3] => 45056971449
)
)
what i want:
Array
(
[0] => (
[cat_id] => 45156381272
[product_ids] => Array
(
[0] => 44990952854
)
)
[1] =>
[cat_id] => 45156381272
[product_ids] => Array
(
[0] => 45054787942
[1] => 45056971448
[2] => 45049917079
[3] => 45056971449
)
)
How do i do this?
My code gets the desired result:
Input Data:
$arrayProducts = [["Cat_name" => 'cat example 1', "product_id" => 44990952854],
["Cat_name" => 'cat example 2', "product_id" => 44990952854],
["Cat_name" => 'cat example 2', "product_id" => 44990952854],
["Cat_name" => 'cat example 2', "product_id" => 44990952854],
["Cat_name" => 'cat example 2', "product_id" => 44990952854]];
$arrayCategories = [["cat_id" => 45156381272, "Cat_name" => 'cat example 1'],
["cat_id" => 45002415686, "Cat_name" => 'cat example 2']];
Code:
I iterate first the categories array and then (inner) the products arrays.
<?php
$resultArray = array();
foreach($arrayCategories as $key => $element2) {
$resultArray[$key] = array("cat_id" => $element2["cat_id"], "products_ids" => array());
foreach($arrayProducts as $element1) {
if($element1["Cat_name"] == $element2["Cat_name"]) {
$resultArray[$key]["products_ids"][] = $element1["product_id"];
}
}
}
?>
Output ($resultArray)
array ( 0 => array ( 'cat_id' => 45156381272, 'products_ids' => array ( 0 => 44990952854, ), ), 1 => array ( 'cat_id' => 45002415686, 'products_ids' => array ( 0 => 44990952854, 1 => 44990952854, 2 => 44990952854, 3 => 44990952854, ), ), );
Keep using the category ID as array index, while you are building the array. That is (IMHO) the most efficient way to accumulate the data under that ID - otherwise, you would have to search your array for the index of the item with the category ID of the current record all the time.
Add another dimension below that, for the category ID, and the product IDs:
$cat_db_row[$cat_name_db_id]['cat_id'] = $cat_name_db_id;
$cat_db_row[$cat_name_db_id]['product_ids'][] = $cat_name_product_id;
(Technically, that first line overwrites $cat_db_row[$cat_name_db_id]['cat_id'] again and again - but since it is always with the same category ID value, that doesn’t matter. You could do a check whether $cat_db_row[$cat_name_db_id]['cat_id'] is already set first, but that would have rather little point.)
“Reset” the array keys afterwards, when you are done filling the array, using
$cat_db_row = array_values($cat_db_row);
This will throw away all the existing (top-level) array keys, and re-index the array numerically, starting at 0.
Related
I have multi-dimentional array like below,
$product = array(
"2e471a22b1b994a7cb3f3a40cee9fba2" => array (
"product" => 6004,
"unique_key" => 3a8a5cb029ee3b92cfc90de23e2329ab,
"product_id" => 51,
"line_total"=>99,
"quantity"=>1,
"data"=> array(
"id"=> 51,
"post"=>array(
"ID"=>51,
"post_title"=>"Prodcut four - control",
),
"price"=>99
)
),
"a7d0f813832ec8a2bf24269ff7145d0c" => array (
"product" => 6004,
"unique_key" => c30d1ca26d30aa3dc3c9aa04f0b585ce,
"product_id" => 51,
"line_total"=>99,
"quantity"=>1,
"data"=> array(
"id"=> 51,
"post"=>array(
"ID"=>51,
"post_title"=>"Prodcut four - control",
),
"price"=>99
)
)
);
Need to remove the duplicate values based on 'product_id' array value and increase the quantity values based on number of products.
Note: The above array have 'unique key' too so any single unique key is needed in array result.
Expected Result should be:
$resultproduct = array(
"2e471a22b1b994a7cb3f3a40cee9fba2" => array (
"product" => 6004,
"unique_key" => 3a8a5cb029ee3b92cfc90de23e2329ab,
"product_id" => 51,
"line_total"=>99,
"quantity"=>2,
"data"=> array(
"id"=> 51,
"post"=>array(
"ID"=>51,
"post_title"=>"Prodcut four - control",
),
"price"=>99
)
));
Working code at eval.in
I try and make the code easy to understand so more variables and lines of code than is absolutely required.
Explanation:
1) Need to use the one of original product array index as the output table key e.g. "2e471a22b1b994a7cb3f3a40cee9fba2" for product 51.
2) It needs to be fast relating input productId to the output key. So, I used a lookup table ProductIdList that matches productId to output key.
It is then a two stage lookup to find the entry in the output and add quantities to it.
The code:
// create a product_id => first key table
$productIdList = array();
// output...
$productTotal = array();
foreach ($product as $origIndex => $entry) {
$curProductId = $entry['product_id'];
// check product_id exists in the lookup...
if (isset($productIdList[$curProductId])) { // add to the total...
$productTotalIndex = $productIdList[$curProductId];
$productTotal[$productTotalIndex]['quantity'] += $entry['quantity'];
}
else { // add the entry to the output and the productIdList...
$productIdList[$curProductId] = $origIndex;
$productTotal[$origIndex] = $entry;
}
}
Output: The totals array:
Array
(
[2e471a22b1b994a7cb3f3a40cee9fba2] => Array
(
[product] => 6004
[unique_key] => 3a8a5cb029ee3b92cfc90de23e2329ab
[product_id] => 51
[line_total] => 99
[quantity] => 2
[data] => Array
(
[id] => 51
[post] => Array
(
[ID] => 51
[post_title] => Prodcut four - control
)
[price] => 99
)
)
[test02] => Array
(
[product] => 6664
[unique_key] => c30d1ca26d30aa3dc3c9aa04f0b585ce
[product_id] => 666
[line_total] => 99
[quantity] => 579
[data] => Array
(
[id] => 666
[post] => Array
(
[ID] => 666
[post_title] => Prodcut 666 - control
)
[price] => 99
)
)
)
The productId to original key list:
array (size=2)
51 => string '2e471a22b1b994a7cb3f3a40cee9fba2' (length=32)
666 => string 'test02' (length=6)
You need to loop over each product and use the product_id as the key for a new array. This adds the quantities as it goes, so should work for any quantities other than 1.
$result = [];
foreach ($product as $p)
{
if (isset($result[$p['product_id']]))
{
$result[$p['product_id']]['quantity']+= $p['quantity'];
}
else
{
$result[$p['product_id']] = $p;
}
}
print_r($result);
I've got a dynamic form that allows a user to create as many form elements as they need -- then submit them. For this, I have prepared the input names as arrays like
<input name="title[]" ...
and posting them gives me output like
Array
(
[day] => 0
[project_id] => 5
[submit] => publish
[id] => Array
(
[0] => 4
[1] => 5
)
[title] => Array
(
[0] => Step 1
[1] => Step 2
)
[max_vol] => Array
(
[0] => 2
[1] => 3
)
[description] => Array
(
[0] => df dofi dofidfoi
[1] => dfvpdofvdpfo osd pod
)
)
I've created something that allows me to just grab the post arrays like so
foreach( $_POST as $post_key ) {
// ignore non-array post variables
if( is_array( $post_key ) ) {
foreach( $post_key as $form_value ) {
echo "$form_value\n";
}
}
}
/* ouputs...
4
5
Step 1
Step 2
2
3
df dofi dofidfoi
dfvpdofvdpfo osd pod
*/
which nicely sorts the non-arrays from the arrays, but I can't figure out how to take this variable number of created form elements and prepare them into an array variable that looks something like...
Array
(
[0] => Array
(
'id' => 4, 'title' => 'Step 1', 'max_vol' => '2', 'description' => 'df dofi dofidfoi'
),
[1] => Array
(
'id' => 5, 'title' => 'Step 2', 'max_vol' => '3', 'description' => 'dfvpdofvdpfo osd pod'
),
// could be more or less elements...
);
(I will be eventually passing these arrays to a MySQL query builder function).
Thanks.
How about creating a variable that is outside the scope of the foreach loop
$results = array();
foreach( $_POST as $post_key=>$post_value ) {
// ignore non-array post variables
if( is_array( $post_value ) ) {
foreach( $post_value as $form_key=>$form_value ) {
if (!isset($results[$form_key]))
{
$results[$form_key] = array();
}
$results[$form_key][$post_key] = $form_value;
}
}
}
// results is your array variable
print_r($results);
Iterate over some significant $_POST-array key, for example - id and get the values from other $_POST-arrays with the same index:
$values = array();
foreach ($_POST['id'] as $k => $v) {
$values[] = array(
'id' => $v,
'title' => $_POST['title'][$k],
'max_vol' => $_POST['max_vol'][$k],
'description' => $_POST['description'][$k],
);
}
print_r($values);
So i have this array:
$input = array (
1 => array (
'TitleName' => 'Details',
'TitleID' => 1,
1 => array (
'ID' => 1,
'Name' => 'First Name'
),
2 => array (
'ID' => 2,
'Name' => 'Last Name'
),
3 => array (
'ID' => 4,
'Name' => 'City')
),
12 => array (
'TitleName' => 'System',
'TitleID' => 12,
0 => array (
'ID' => 3,
'Name' => 'Cpu'
)
)
);
And i have an Array that tells me how to order the array above:
$order = array
(
1 => array(
0 => 1, // this is the ID in the third dimension
1 => 4,
2 => 2,
),
12 => array (
0 => 3
)
);
So the point is that i will get in my final array :
Array
(
[1] => Array
(
[TitleName] => Details
[TitleID] => 1
[1] => Array
(
[ID] => 1
[Name] => First Name
)
[2] => Array
(
[ID] => 4
[Name] => City
)
[3] => Array
(
[ID] => 2
[Name] => Last Name
)
)
[12] => Array
(
[TitleName] => System
[TitleID] => 12
[0] => Array
(
[ID] => 3
[Name] => Cpu
)
)
)
Also, how can i move items inside the array to different parent?
I've tried this code, but no luck.
usort($array, function ($a, $b) use ($order) {
$pos_a = array_search($a['id'], $order);
$pos_b = array_search($b['id'], $order);
return $pos_a - $pos_b;
});
Any ideas?? Thanks!
Since your id's are unique, it might be easier to just fill two temporary arrays and then iterate over the ordering array to create your desired output.
Here's a possible solution. No need for array_search here.
Having your two goven arrays, we'll first iterate over the input, seperating the common 1st level elements and it's attributes and the children elements.
To distinguish between attributes of first level elements and chiuldren we use is_numeric on the key (since attribute keys are not numeric) and is_array (just to be sure).
// our temporary arrays
$tmpElements = array();
$tmpChildren = array();
// iterate over array
foreach($input as $key => $value) {
$tmpElementAttributes = array(); // init/reset the temporary attributes array
// iterate over children and attributes
foreach ($value as $subKey => $subValue) {
// if the value is an array and the key is numeric, it is a child element
if(is_array($subValue) && is_numeric($subKey)) {
$tmpChildrenKey = $subValue['ID'];
$tmpChildren[$tmpChildrenKey] = $subValue;
}
else { // otherwise it is an attribute
$tmpElementAttributes[$subKey] = $subValue;
}
}
$tmpElements[$key] = $tmpElementAttributes; // add the gathered attributes that define our firstLevel Element
}
So now we have two arrays. One ($tmpElements) has all the first Level Elements (Details, Systems) and the other one ($tmpChildren) has all the child Elements (First Name, Last Name, Cpu, City). For both arrays we took their id's as array key.
Now we iterate over the ordering array, filling in our child elements into the respective first level elements in our $tmpElements Array accoring to $order.
foreach($order as $key => $values) {
foreach($values as $orderId) {
$tmpElements[$key][] = $tmpChildren[$orderId];
}
}
Here, $key from the first array is the array key for our first level element, both in order as in your source/input and as in our $tmpElements. So we can use it to identify elements in our array.
The $orderId from the second foreach is the second level children element ID.
So we use it to reach our respective Children Element.
Hence: $tmpElements[$key][] = $tmpChildren[$orderId];
I have got this array
Array
(
[0] => Array
(
[category_name] => Dessert1
[totalOrders] => 3
)
[1] => Array
(
[category_name] => Dessert1
[totalOrders] => 1
)
[2] => Array
(
[category_name] => Category 3
[totalOrders] => 1
)
)
and I want to convert it into this array
Array
(
[0] => Array
(
[category_name] => Dessert1
[totalOrders] => 4
)
[1] => Array
(
[category_name] => Category 3
[totalOrders] => 1
)
)
It is really rather simple. You just loop over your data and pick out the unique categories. When there are duplicates add the orders to the category's total.
// The stuff from your post
$data = array(
array('category_name' => 'Dessert1', 'totalOrders' => 3),
array('category_name' => 'Dessert1', 'totalOrders' => 1),
array('category_name' => 'Category 3', 'totalOrders' => 1),
);
// Auxiliary variable
$result = array();
// Go over the data one by one
foreach ($data as $item)
{
// Use the category name to identify unique categories
$name = $item['category_name'];
// If the category appears in the auxiliary variable
if (isset($result[$name]))
{
// Then add the orders total to it
$result[$name]['totalOrders'] += $item['totalOrders'];
}
else // Otherwise
{
// Add the category to the auxiliary variable
$result[$name] = $item;
}
}
// Get the values from the auxiliary variable and override the
// old $data array. This is not strictly necessary, but if you
// want the indices to be numeric and in order then do this.
$data = array_values($result);
// Take a look at the result
var_dump($data);
I have a PHP/MySQL e-commerce site that is placing order detail information into a serialized array alongside customer address info.
I want to be able to pull out the order items field, unserialize it and then combine the order items into one master array of ALL ordered items that can be manipulated in order to count how many orders of a specific product have been made.
The arrays look like this when I print_r the unserialized rows. Below are two order arrays, one with 3 products, and the second with only one.
The array values are ID #, SKU #, Quantity, Product Name, Price.
I want to be able to combine ALL orders into one array and then sum the total quantities for each unique ID or SKU number.
I realize this type of thing is drop dead simple if the data was clean in MySQL, but such is life. Any thoughts on how to manipulate these arrays would be truly appreciated.
In this case want to end up with 4 arrays, with the 629/01-3600 ones being combined such that the quantity value is now 2
Many thanks.
Array
(
[0] => Array
(
[1] => 488
[5] => 23-1000
[2] => 3
[3] => PRODUCT NAME
[4] => 2.50
)
[1] => Array
(
[1] => 423
[5] => 24-2300
[2] => 1
[3] => PRODUCT NAME
[4] => 3.50
)
[2] => Array
(
[1] => 506
[5] => 23-2800
[2] => 1
[3] => PRODUCT NAME
[4] => 2.50
)
[3] => Array
(
[1] => 629
[5] => 01-3600
[2] => 1
[3] => PRODUCT NAME
[4] => 7.50
)
)
Array
(
[0] => Array
(
[1] => 629
[5] => 01-3600
[2] => 1
[3] => PRODUCT NAME
[4] => 7.50
)
)
EDIT:
I wanted to add what eventually did what I was looking for
foreach($query->result as $row)
{
$items[] = unserialize( $row['FIELDNAME'] );
}
foreach($items as $item)
{
foreach($item as $order)
{
if( isset($output_array[$order[1]]) )
{
$output_array[$order[1]]['quantity'] += $order[2];
}
else
{
$output_array[$order[1]] = array (
'name' => $order[3],
'quantity' => $order[2],
'sku' => $order[5]
);
}
}
}
I then used this sorting function to sort on the quantity: http://www.php.net/manual/en/function.sort.php#99419
This is a little bit of code so I've separated it into chunks.
This is my recreation of your two arrays. The last line puts them into one.
$items = array(
array(
1 => 488,
5 => '23-1000',
2 => 3,
3 => 'PRODUCT NAME',
4 => 2.50
),
array(
1 => 423,
5 => '24-2300',
2 => 1,
3 => 'PRODUCT NAME',
4 => 3.50
),
array(
1 => 506,
5 => '23-2800',
2 => 1,
3 => 'PRODUCT NAME',
4 => 2.50
),
array(
1 => 629,
5 => '01-3600',
2 => 1,
3 => 'PRODUCT NAME',
4 => 7.50
)
);
$array_2 = array(
array(
1 => 629,
5 => '01-3600',
2 => 1,
3 => 'PRODUCT NAME',
4 => 7.50
)
);
// Put the two arrays together (master array)
$new_array = array_merge($items, $array_2);
Next, we create two arrays to that will use the SKU# and another for the IDs.
// What the items will be sorted by
$skus = array();
$ids = array();
The more complicated part
// Loop through the combined items
foreach( $new_array as $item ) {
/**
* Check if the item's SKU number
* has been added to the $skus array.
*
* If it has then add the old qty with the current item's
*
* Else, the item hasn't been added yet,
* then add the entire item to the list
*/
if( isset($skus[$item[5]]) ) {
// If it exists, then add the new qty
$skus[$item[5]][2] += $item[2];
}else {
// If it doesn't exist, then append it to the array
$skus[$item[5]] = $item;
}
// Do the same thing as above
// except for the id numbers
if( isset($ids[$item[1]]) ) {
// If it exists, then add the new qty
$ids[$item[1]][2] += $item[2];
}else {
// If it doesn't exist, then append it to the array
$ids[$item[1]] = $item;
}
}
Make sure everything is the way you want it
echo '<h2>SKU Numbers</h2>';
echo '<pre>';
print_r($skus);
echo '</pre>';
echo '<h2>ID Numbers</h2>';
echo '<pre>';
print_r($ids);
echo '</pre>';
Hope this helps.
EDIT
For this code to work during the actual loop, you can try something like this. While I'm not completely sure if this will work out of the box, it should be a good place to start.
// What the items will be sorted by
$skus = array();
$ids = array();
foreach( $result as $row ) {
$row = unserialize($row);
/**
* MODIFIED
*
* Check if the $row's SKU number
* has been added to the $skus array.
*
* If it has then add the old qty with the current $row's qty
*
* Else, the $row hasn't been added yet,
* then add the entire $row to the list
*/
if( isset($skus[$row[5]]) ) {
// If it exists, then add the new qty
$skus[$row[5]][2] += $row[2];
}else {
// If it doesn't exist, then append it to the array
$skus[$row[5]] = $row;
}
// Do the same thing as above
// except for the id numbers
if( isset($ids[$row[1]]) ) {
// If it exists, then add the new qty
$ids[$row[1]][2] += $row[2];
}else {
// If it doesn't exist, then append it to the array
$ids[$row[1]] = $row;
}
}