I am needing to create a multidimensional array with sql and loops. However only one result gets set into the array, the last result is overwriting the previous results. Here is what the array structure looks like:
->value = Array (4)
CartID => "1299"
Date => "2012-09-27 09:17:20"
Amount => "85.00"
0 => Array (8)
CartStatus => "Purchased"
Date => "2012-09-27 09:17:20"
CartID => "1299"
Sequence => "1"
Amount => "-85.00"
Comments => " , Refund Status: "
Here is my code:
$txarray = array();
foreach ($data as $transaction) {
$CartVar = $transaction['CartID'];
$CartStatus = $transaction['Status'];
$CartDate = $transaction['DateTime'];
$CartTotal = $transaction['Total'];
$txarray = array('CartID' => $CartVar, 'Date' => $CartDate, 'Amount' => $CartTotal);
$sql1 = $db->query("SQL stuff");
foreach ($sql1 as $refund) {
$CartID = $refund['CartID'];
$Sequence = $refund['Sequence'];
$TrxType = $refund['TrxType'];
$ParentID = $refund['ParentID'];
$TotalSum = '-'.$refund['Amount'];
$Comments = ' '.$refund['Comments'];
$Comments .= ', Refund Status: '.ucwords($refund['Status']);
$txarray[] = array('CartStatus' => $CartStatus, 'Date' => $CartDate, 'CartID' => $CartID, 'Sequence' => $Sequence, 'TrxType' => $TrxType, 'ParentID' => $ParentID, 'Amount' => $TotalSum, 'Comments' => $Comments);
}
Looking at above code snippet $txarray variable is overwritten due to code.
$txarray = array('CartID' => $CartVar, 'Date' => $CartDate, 'Amount' => $CartTotal);
It needs to be replaced it with
$txarray[] = array('CartID' => $CartVar, 'Date' => $CartDate, 'Amount' => $CartTotal);
or alternatively you can use array_push() function which will push arrays thereby resulting into multidimensional array.
e.g.
array_push($txarray,array('CartID' => $CartVar, 'Date' => $CartDate, 'Amount' => $CartTotal));
For more documentation about array_push function please refer the documentation in below mentioned url.
http://php.net/manual/en/function.array-push.php
This line:
$txarray = array('CartID' => $CartVar, 'Date' => $CartDate, 'Amount' => $CartTotal);
destroys any previous array'd you'd created in earlier iterations.
Related
What I'm trying to accomplish is to write a html string in a controller with array values being looped in it. So for example;
$content = "Your store, at location A, has these items added to them". add array loop here. "Do take note!";
My array would be as such
array (
0 =>
array (
'id' => '5db29b6d31c391731239bbdf',
'name' => 'Diamond bracelet (sample)',
'tags' =>
array (
0 => 'female',
1 => 'jewelry',
),
'category' => 'Accessories',
'sku' => '1029EHW',
'priceType' => 'Fixed',
'unitPrice' => 190,
'cost' => 90,
'trackStockLevel' => true,
'isParentProduct' => false,
),
1 =>
array (
'id' => '5db29b6d31c391731239bbdb',
'name' => 'Long-sleeved shirt(sample)(M)',
'tags' =>
array (
0 => 'tops',
1 => 'cotton',
),
'category' => 'Women\'s Apparel',
'sku' => 'ABC1234-M',
'priceType' => 'Fixed',
'unitPrice' => 47.170000000000002,
'cost' => 20,
'trackStockLevel' => true,
'isParentProduct' => false,
'parentProductId' => '5db29b6d31c391731239bbd4',
'variationValues' =>
array (
0 =>
array (
'variantGroupId' => '5db29b6d31c391731239bbd5',
'value' => 'M',
),
),
),
)
note that the array can have many instances of product_name and sku, or can have none.
How do i populate this in my string to be like;
$content = "Your store, at location A, has these items added to them, 1) asd, 2)def, 3)asf . Do take note!
Try this, I've used \sprintf for ease, check if the output serves your purpose.
<?php
function stringMethod(): string
{
$count = 0;
$arrayString = [];
$array = [['product_name' => 'abc', 'product_sku' => 'def'],['product_name' => 'abc', 'product_sku' => 'asd']];
foreach ($array as $value){
$count++;
$arrayString[] = sprintf('%s)%s', $count, $value['product_sku']);
}
$string = \implode(',', $arrayString);
return \sprintf("Your store, at location A, has these items added to them %s Do take note!", $string);
}
echo stringMethod();
Hope this will help you. try to do it in less number of lines
$content = "Your store, at location A, has these items added to them, ";
$productArray = array (0 => array ('id' => '5db29b6d31c391731239bbdf','name' => 'Diamond bracelet (sample)','tags' => array (0 => 'female',1 => 'jewelry',),'category' => 'Accessories','sku' => '1029EHW','priceType' => 'Fixed','unitPrice' => 190,'cost' => 90,'trackStockLevel' => true,'isParentProduct' => false,),1 => array ('id' => '5db29b6d31c391731239bbdb','name' => 'Long-sleeved shirt(sample)(M)','tags' => array (0 => 'tops',1 => 'cotton',),'category' => 'Women\'s Apparel','sku' => 'ABC1234-M','priceType' => 'Fixed','unitPrice' => 47.170000000000002,'cost' => 20,'trackStockLevel' => true,'isParentProduct' => false,'parentProductId' => '5db29b6d31c391731239bbd4','variationValues' => array (0 => array ('variantGroupId' => '5db29b6d31c391731239bbd5','value' => 'M'))));
foreach ($productArray as $key => $product) {
$content .= ($key+1).') '.$product['name'];
if (count($productArray)-1!=$key) {
$content .= ', ';
}
}
$content .= ". Do take note!";
$content = "Your store, at location A, has these items added to them,". $this->getItemList($collection) .". Do take note!"
# Somewhere else in the controller
protected function getItemList(Collection $collection): string
{
return $collection->pluck('name')
->merge($collection->pluck('sku'))
->map(function($item, $key) {
return ($key + 1) . ') ' . $item;
})
->implode(', ');
}
An easy solution would be
$content = "Your store, at location A, has these items added to them";
$array = array(0=>["product_name" => "abc", "product_sku" => "def"], 1=>['product_name' => 'kdkf', 'product_sku'=> 'ljbkj']);
for($i = 0; $i<count($array); $i++){
$content .= ($i+1).") ".$array[$i]['product_name].' '.$array[$i]['product_sku'].', ';
}
$content .= "Do take note.";
This way you're just constantly concatonating the string value in separate parts instead of trying to inject it in the middle of the parent string.
not tested, may be syntax errors
I have a multidimensional array that has a date, name, & markup.
$in = [
[
'saledate' => '2016-02-01',
'name' => 'John Doe',
'markup' => 561
],
[
'saledate' => '2016-02-01',
'name' => 'John Doe',
'markup' => 681
],
[
'saledate' => '2016-02-02',
'name' => 'John Doe',
'markup' => 379
],
[
'saledate' => '2016-02-01',
'name' => 'Jane Doe',
'markup' => 205
],
[
'saledate' => '2016-02-02',
'name' => 'Jane Doe',
'markup' => 900
],
[
'saledate' => '2016-02-02',
'name' => 'Jane Doe',
'markup' => 787
],
[
'saledate' => '2016-02-03',
'name' => 'Jane Doe',
'markup' => 211
]
]
I'm trying to sum the values for each person by date for the desired output:
0 =>
array (size=3)
'name' => string 'John Doe' (length=8)
'2016-02-01' => float 1242
'2016-02-02' => float 379
1 =>
array (size=3)
'name' => string 'Jane Doe' (length=8)
'2016-02-01' => float 205
'2016-02-02' => float 1687
'2016-02-03' => float 211
Here is what I have but I think I'm just confusing myself...
$out = array();
foreach ($in as $row)
{
$result[$row['saledate']]['saledate'] = $row['saledate'];
$result[$row['name']]['name'] = $row['name'];
$result[$row['date']]['markup'] += $row['markup'];
}
$out = array_values($out);
Store the name as the key in your output array, it'll make grouping the results easier:
$out = array();
foreach ($in as $row) {
/* set the key using the name, eg. $out['John Doe'] */
if (! isset($out[$row['name']])) {
$out[$row['name']] = array('name' => $row['name']);
}
/* if the saledate isn't already exist, set it */
if (! isset($out[$row['name']][$row['saledate']])) {
$out[$row['name']][$row['saledate']] = 0;
}
/* add the markup */
$out[$row['name']][$row['saledate']] += $row['markup'];
}
Which would give you:
Array
(
[John Doe] => Array
(
[name] => John Doe
[2016-02-01] => 1242
[2016-02-02] => 379
)
[Jane Doe] => Array
(
[name] => Jane Doe
[2016-02-01] => 205
[2016-02-02] => 1687
[2016-02-03] => 211
)
)
If you don't want the name key, just use $out = array_values($out).
Try this code:
$result = array();
array_walk(
$in,
function ($row) use (&$result) {
$key = array_search($row['name'], array_column($result, 'name'));
if ($key === False) {
$key = array_push($result, array('name' => $row['name'])) - 1;
}
$date = $row['saledate'];
if (!isset($result[$key][$date]))
$result[$key][$date] = $row['markup'];
else
$result[$key][$date] += $row['markup'];
}
,
$result
);
print_r($result);
3v4l.org demo
After init an empty array, we pass it by reference as second arguments to array_walk: inside the called function, we check if the name and date already exists: if it is, we add the current value, otherwise we create new element(s) with current value.
See more about array_walk()
See more about array_column() PHP > 5.5
See more about passing by reference
Assigning temporary first level keys to the result array can be avoided by pushing reference variables into the result array then manipulating only the references as needed.
Code: (Demo)
$result = [];
foreach ($in as ['saledate' => $s, 'name' => $n, 'markup' => $m]) {
if (!isset($ref[$n])) {
$ref[$n] = ['name' => $n, $s => $m];
$result[] = &$ref[$n];
} else {
$ref[$n][$s] = ($ref[$n][$s] ?? 0) + $m;
}
}
var_export($result);
I am creating a new array ($Parts) from an existing array ($newarray), and reordering the array. However if the array key exists in the new array, I want to append to the 'location' and 'qty' arrays.
Here is what the new array structure looks like:
'4117-0171-249' =>
'pri_id' => '859'
'vendor' => 'R01298'
'score' => '0.00'
'location' =>
0 => '10103'
'qty' =>
0 => '70'
Here is my code I am using.
$Parts = array();
foreach($newarray AS $Ke => $Va) {
if(array_key_exists($Va['part_number'], $Parts)){
array_push($Parts[$location][],$Va['location']);
} else {
$Parts[$Va['part_number']] = array('pri_id' => $Va['pri_id'],
'vendor' => $Va['vendor'],
'score' => $Va['Score'],
'location' => array($Va['location']),
'qty' => array($Va['qty']),
);
}
}
If anyone stumbles across this in the future, the answer was this:
$Parts[$Va['part_number']]['location'][] = $Va['location'];
I am trying to create an array of arrays in a loop to a JSON object, but It returns two objects instead. If I remove the array around the array with a key, it works but I need the key.
This is the format I am looking for:
$shop = array( "1408842145690" => array( id => "1408842145690",
code => "1",
title => "zdfdsf",
date => "2014-08-01",
description => "fghgf"
),
"1408840099517" => array( id => "1408840099517",
code => "1",
title => "test",
date => "2014-08-01",
description => "this is a test"
)
);echo json_encode($shop);
This is the code I am using
$query = " SELECT * FROM todolist ";
if ($result = mysqli_query($mysqli,$query)) {
while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
$tasks = array(
$row['task_id'] => array( 'id' => $row['task_id'],
'code' => $row['task_statusbox'],
'title' => $row['task_title'],
'date' => $row['task_date'],
'description' => $row['task_description']
)
);
$alltasks[] = $tasks;
}
echo json_encode($alltasks);
/* free result set */
$result->close();
}
This is the result I get:
{"1408842145690":{"id":"1408842145690","code":"1","title":"zdfdsf","date":"2014-08-01 00:00:00","description":"fghgf"}},{"1408840099517":{"id":"1408840099517","code":"1","title":"test","date":"2014-08-01 00:00:00","description":"this is a test"}}
This is the result I am looking for
{"1408842145690":{"id":"1408842145690","code":"1","title":"zdfdsf","date":"2014-08-01","description":"fghgf"},"1408840099517":{"id":"1408840099517","code":"1","title":"test","date":"2014-08-01","description":"this is a test"}}
Replace the contents of your while loop with the following:
$tasks = array('id' => $row['task_id'],
'code' => $row['task_statusbox'],
'title' => $row['task_title'],
'date' => $row['task_date'],
'description' => $row['task_description']
);
$alltasks[$row['task_id']] = $tasks;
EDIT: I tested the above, and it does work. Here is the full code with the replacement intact... try a copy/paste.
$query = " SELECT * FROM todolist ";
if ($result = mysqli_query($mysqli,$query)) {
while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
$tasks = array('id' => $row['task_id'],
'code' => $row['task_statusbox'],
'title' => $row['task_title'],
'date' => $row['task_date'],
'description' => $row['task_description']
);
$alltasks[$row['task_id']] = $tasks;
}
echo json_encode($alltasks);
/* free result set */
$result->close();
}
If I had an array:
$data = array(
array(
'manufacturers_id' => 29,
'manufacturers_name' => 'Quicksilver',
'products_quantity' => 1,
'products_price' => 15.6000,
'products_cost' => 8.0000,
),
array(
'manufacturers_id' => 29,
'manufacturers_name' => 'Quicksilver',
'products_quantity' => 2,
'products_price' => 4.6722,
'products_cost' => 2.4000,
)
);
How can I reformat this to provide the structure
Array
(
[Quiksilver] => Array
(
[brands_sales] => $brandsSalesVal
[brands_products_sold] => $brandsSoldVal
[brands_costs] => $brandsCostsVal
)
$brandsSalesVal = A sum of all the products_price * products_quantity (for each manufacturer_id)
$brandsSoldVal= A sum of all the products_quantity for each manufacturer
$brandsCostsVal= A sum of all the products_costs for each manufacturer
Any help is greatly appreciated and I am thankful for anyone to take time to answer my rather lengthy query. I am still getting to grips with reformating arrays.
You need to use a foreach loop like so:
// Declare the totals array and
// the manufacturers->id map
$totals = array();
$manufacturers = array();
// Loop through the array of products and populate
// the totals array
foreach($data as $value){
// Set the key to the manufacturers name
$key = $value['manufacturers_name'];
// If the array has not been built yet, then ensure the
// values are set to 0 and add the manufacturer to the
// manufacturers map if it is not already there
if(!isset($totals[$key])){
// Add the manufacturer to the map
$manufacturers[$value['manufacturers_id']] = $key;
// Default the values to 0
$totals[$key]['brand_sales'] = 0;
$totals[$key]['brands_products_sold'] = 0;
$totals[$key]['brands_costs'] = 0;
}
// Calculate the brand sales
$totals[$key]['brand_sales'] += ($value['products_price']*$value['products_quantity']);
// Calculate the brand sales
$totals[$key]['brands_products_sold'] += $value['products_quantity'];
// Calculate the brand sales
$totals[$key]['brands_costs'] += $value['products_cost'];
}
In order to access the information stored in the array generated above, you can use another foreach loop like so:
// Loop through the $totals array and print the result
foreach($totals as $key => $value){
// Print the manufacturers name and ID
echo "\n".$key." (ID: ".array_search($key,$manufacturers).")";
// Print the totals for the current manufacturer
echo "\n\tBrand Sales: ".$values['brand_sales'];
echo "\n\tBrand Products Sold: ".$values['brands_products_sold'];
echo "\n\tBrand Costs: ".$values['brands_costs'];
}
The array_search function is used to look up the ID of the manufacturer based on the manufacturers name stored in the $manufacturers array. You can alter the code so that it does not need the array_search function, but I have done it like this because traditionally you would map the ID->NAME, not NAME->ID. It is just personal preference...
For more information on the foreach loop, see here
$data = array(
array(
'manufacturers_id' => 29,
'manufacturers_name' => 'Quicksilver',
'products_quantity' => 1,
'products_price' => 15.6000,
'products_cost' => 8.0000,
),
array(
'manufacturers_id' => 29,
'manufacturers_name' => 'Quicksilver',
'products_quantity' => 2,
'products_price' => 4.6722,
'products_cost' => 2.4000,
)
,
array(
'manufacturers_id' => 30,
'manufacturers_name' => 'Different Brand',
'products_quantity' => 2,
'products_price' => 4.6722,
'products_cost' => 2.4000,
)
);
$sortedData = array();
foreach($data as $num => $row){
$manufacturersName = $row['manufacturers_name'];
//If we don't have an array made for the manufacturer yet, make one
if(!isset($sortedData[$manufacturersName])){
$sortedData[$manufacturersName] = array(
'brands_sales' => 0,
'brands_products_sold' => 0,
'brands_costs' => 0
);
};
//Make a reference to the relevant manufacturer sorted data
$manufacturerData = &$sortedData[$manufacturersName];
$qty = $row['products_quantity'];
//
$manufacturerData['brands_sales'] += $qty * $row['products_price'];
$manufacturerData['brands_products_sold'] += $qty;
$manufacturerData['brands_costs'] += $row['products_cost'];
}
var_dump($sortedData); // <- your result.
Result:
array (size=2)
'Quicksilver' =>
array (size=3)
'brands_sales' => float 24.9444
'brands_products_sold' => int 3
'brands_costs' => float 10.4
'Different Brand' =>
array (size=3)
'brands_sales' => float 9.3444
'brands_products_sold' => int 2
'brands_costs' => float 2.4