I have an associative array that is I am creating from an ODBC query with the following code:
while ($row=odbc_fetch_array($oexec)) {
if(empty($group[$row['gmm']])) {
$group[$row['gmm']] = array();
}
if(empty($group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']])) {
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']] = array();
}
if(empty($group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']])) {
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']] = array();
}
if(empty($group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']])) {
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']] = array();
}
if(empty($group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']])) {
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']] = array();
}
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['total_ty_yest_sales'] = $row['total_ty_yest_sales'];
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['total_wo_dotcom_ty_yest_sales'] = $row['total_wo_dotcom_ty_yest_sales'];
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['east_ty_yest_sales'] = $row['east_ty_yest_sales'];
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['central_ty_yest_sales'] = $row['central_ty_yest_sales'];
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['west_ty_yest_sales'] = $row['west_ty_yest_sales'];
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['dotcom_ty_yest_sales'] = $row['dotcom_ty_yest_sales'];
}
This gives me an array where:
$myArray = Array(GMM => Array(acctg_dept_nbr => Array(dept_category_desc => Array(dept_subcatg_desc => Array(value1,value2,value3)))))
I want to sum the values at every level. So for every acctg_dept_nbr[dept_category_desc][dept_subcatg_desc] I want to sum value1,value2,value3. Same for the GMM level and down to the dept_subcatg_desc level. Summing the dept_subcatg_desc level wasn't a problem. I dug around and found how to sum the dept_category_desc level, but am having trouble applying that method recursively.
Here is the code that puts the values into a table:
foreach($group as $gmm => $acctg_dept_nbrs) {
echo "<tr class=\"header\">
<td>" . $gmm . "</td>\n";
foreach ($acctg_dept_nbrs as $acctg_dept_nbr => $dept_catg_grp_descs) {
echo "<tr class=\"header\">\n
<td style=\"padding-left: 1em;\">" . $acctg_dept_nbr . "</td>\n";
foreach($dept_catg_grp_descs as $dept_catg_grp_desc => $dept_category_descs) {
echo "<tr class=\"header\">\n
<td style=\"padding-left: 2em;\">" . $dept_catg_grp_desc . "</td>\n";
//echo "<td>" . array_sum(array_walk_recursive($dept_category_descs,function($item) {return $item['total_ty_yest_sales'];})) . "</td>";
foreach($dept_category_descs as $dept_category_desc => $dept_subcatg_descs) {
echo "<tr class=\"header\">\n
<td style=\"padding-left: 3em;\">" . $dept_category_desc . "</td>\n";
echo "<td>" . array_sum(array_map(function($item) {return $item['total_ty_yest_sales'];},$dept_subcatg_descs)) . "</td>";
echo "<td>" . array_sum(array_map(function($item) {return $item['east_ty_yest_sales'];},$dept_subcatg_descs)) . "</td>";
echo "<td>" . array_sum(array_map(function($item) {return $item['central_ty_yest_sales'];},$dept_subcatg_descs)) . "</td>";
echo "<td>" . array_sum(array_map(function($item) {return $item['west_ty_yest_sales'];},$dept_subcatg_descs)) . "</td>";
foreach($dept_subcatg_descs as $dept_subcatg_desc => $values) {
echo "<tr>\n
<td style=\"padding-left: 4em;\">" . $dept_subcatg_desc . "</td>\n";
$sum = $values['total_ty_yest_sales'];
echo "<td>".$sum."</td>";
$sum = $values['east_ty_yest_sales'];
echo "<td>".$sum."</td>";
$sum = $values['central_ty_yest_sales'];
echo "<td>".$sum."</td>";
$sum = $values['west_ty_yest_sales'];
echo "<td>".$sum."</td>";
}
}
}
}
}
The commented out line is the problem for me now. This:
array_sum(array_map(function($item) {return $item['west_ty_yest_sales'];},$dept_subcatg_descs))
works fine at that level, but not at the higher levels. I have also tried to tweak this function to no avail:
function array_map_recursive($callback, $array) {
foreach ($array as $key => $value) {
if (is_array($array[$key])) {
$array[$key] = array_map_recursive($callback, $array[$key]);
}
else {
$array[$key] = call_user_func($callback, $array[$key]);
}
}
return $array;
}
How can I make this work so that regardless of level it will dig down and sum the values for that portion of the array?
function array_map_recursive($callback, $array)
{
$func = function ($item) use (&$func, &$callback) {
return is_array($item) ? array_map($func, $item) : call_user_func($callback, $item);
};
return array_map($func, $array);
}
function array_map_recursive($callback, $array)
{
if(is_array($callback)){
foreach ($callback as $function){
$array = array_map_recursive($function, $array);
}
return $array;
}
$func = function ($item) use (&$func, &$callback) {
return is_array($item) ? array_map($func, $item) : call_user_func($callback, $item);
};
return array_map($func, $array);
}
This way you can call the function passing more functions.. ex:
$rowData = array_map_recursive(['utf8_decode', 'trim'], $rowData);
Or simple call just one:
$rowData = array_map_recursive('trim', $rowData);
It can be a little difficult if we add multiple arrays to the function. But with only one, there is no problem at all.
function array_map_recursive(&$arr, $fn) {
return array_map(function($item) use($fn){
return is_array($item) ? array_map_recursive($item, $fn) : $fn($item);
}, $arr);
}
$array = array_map_recursive($array, function($item){
//TODO logic here
});
filter_var can essentially be used to accomplish this
function array_map_recursive(callable $func, array $array) {
return filter_var($array, FILTER_CALLBACK, ['options' => $func]);
}
There is one big drawback...
The callback will receive the value as a string.
and the leafs can't be objects
Related
I have a nested array on this link Array Sample
I am using code below to parse this, but second and beyond depth it's returning nothing. However tried with recursive function.
printAllValues($ArrXML);
function printAllValues($arr) {
$keys = array_keys($arr);
for($i = 0; $i < count($arr); $i++) {
echo $keys[$i] . "$i.{<br>";
foreach($arr[$keys[$i]] as $key => $value) {
if(is_array($value))
{
printAllValues($value);
}
else
{
echo $key . " : " . $value . "<br>";
}
}
echo "}<br>";
}
}
What I am doing Wrong? Please help.
Version of J. Litvak's answer that works with SimpleXMLElement objects.
function show($array) {
foreach ($array as $key => $value) {
if (!empty($value->children())) {
show($value);
} else {
echo 'key=' . $key . ' value=' . $value. "<br>";
}
}
}
show($ArrXML);
You can use recurcive function to print all values:
function show($array) {
foreach( $array as $key => $value) {
if (is_array($value)) {
show($value);
} else{
echo 'key=' . $key . ' value=' . $value. "<br>";
}
}
}
show($ArrXML);
I have the following code which gets me a list of manufacturers:
$attribute = Mage::getModel('eav/entity_attribute')
->loadByCode('catalog_product', 'manufacturer');
$valuesCollection = Mage::getResourceModel('eav/entity_attribute_option_collection')
->setAttributeFilter($attribute->getData('attribute_id'))
->setStoreFilter(0, false);
$preparedManufacturers = array();
foreach($valuesCollection as $value) {
$preparedManufacturers[$value->getOptionId()] = $value->getValue();
}
if (count($preparedManufacturers)) {
echo "<h2>Manufacturers</h2><ul>";
foreach($preparedManufacturers as $optionId => $value) {
echo "<li>" . $value . " - (ID:" . $optionId . ")</li>";
}
echo "</ul>";
}
How do I get the first product of each manufacturer?
Thanks
try this
if (count($preparedManufacturers)) {
echo "<h2>Manufacturers</h2><ul>";
foreach($preparedManufacturers as $optionId => $value) {
<!-- add the this code for get first item id -->
$firstProductId=Mage::getModel('catalog/product')->getCollection()
->addStoreFilter(0)
->addAttributeToFilter('manufacturer',$optionId)->getFirstItem()->getId();
echo "<li>" . $value . " - (ID:" . $optionId . ")</li>";
}
echo "</ul>";
}
I've made a foreach loop that print some variables found in an xml file:
foreach ($xml->result->rowset->row as $row)
{
echo $row["price"] . " " . $row["product"] . "</br>";
}
I would like to get the sum of all the "prices" shown. How can i do?
Just have a variable add up those values as you iterate:
$total = 0; // start with zero
foreach ($xml->result->rowset->row as $row)
{
$total += $row["price"]; // add price to total
echo $row["price"] . " " . $row["product"] . "</br>";
}
echo $total; // echo out total amount
Store the count in a variable:
$total = 0;
foreach ($xml->result->rowset->row as $row) {
echo $row["price"] . " " . $row["product"] . "</br>";
$total += $row['price']; // assumed row_price is some integer
}
echo $total;
Simply add it to a new variable:
$sum = 0;
foreach ($xml->result->rowset->row as $row) {
echo $row["price"] . " " . $row["product"] . "<br />";
$sum += $row["price"];
}
echo $sum . "<br />";
$sum = 0;
foreach ($xml->result->rowset->row as $row)
{
echo $row["price"] . " " . $row["product"] . "</br>";
$sum += $row["price"] ;
}
echo $sum ;
isnt that simple ?
$sum=0;
foreach ($xml->result->rowset->row as $row)
{
echo $row["price"] . " " . $row["product"] . "</br>";
$sum +=$row["price"];
}
echo $sum;
just try this code!!
How do you display the output of a 2 dimensional arrays
Here's the code:
I know how to display both of them separately doing.
foreach($Father as $value){
echo $value[0] . " " . $value[1] . "<br />";
}
foreach($Son as $value){
echo $value[0] . " " . $value[1] . "<br />";
}
try this - it assumes that each father has exactly 1 son though
$i = 0;
foreach($Father as $value){
echo $value[0] . " " . $value[1] . "<br />";
echo "-" . $Son[$i][0] . " " . $Son[$i][1] . "<br />";
$i += 1;
}
In the loop below I want $value[0] to increment on each pass of the loop. So, if $count = 2 the loop will run twice and output $key . " " . $value[0] and $key . " " . $value[1].
Right now, my loop is outputting $key . " " . $value[0] twice. What did I do wrong?
$count = count($updates['positionTitle']);
for($i = 1; $i<=$count; $i++){
foreach($updates as $key => $value){
if(!is_array($value))
echo $key . " " . $value . "<br/>";
else
echo $key . " " . $value[0]++ . "<br/>";
}
}
You need to store what the current index is. I'm not actually sure what loop you were talking about though. I'm assuming it was the outer for loop. I still think this is broken but based on your comment this is what you want.
$count = count($updates['positionTitle']);
$idx = 0;
for($i = 1; $i<=$count; $i++){
foreach($updates as $key => $value){
if(!is_array($value))
echo $key . " " . $value . "<br/>";
else
echo $key . " " . $value[$idx] . "<br/>";
}
$idx++;
}
Change:
foreach($updates as $key => $value){
To:
foreach($updates as $key => &$value){