PHP printing three dimensional array - php

So, I want to print the following three dimensional array in an HTML table.
array ( 'BTC_YACC' => array ( 0 => array ( 'orderNumber' => '3585379', 'type' => 'sell', 'rate' => '0.0001', 'amount' => '128', 'total' => '0.0128', 'date' => '2014-05-18 08:54:37', ), ), )
This is what I came up with: (OrderNumber = OrderID).
$tableopenorders = "<table><th>OrderID</th><th>Type</th><th>Rate</th><th>Amount</th><th>Total in BTC</th><th>Date placed</th><tr>";
for($element = 0; $element < count($decodedopenorders); $element++) {
$tableopenorders .= "<tr>";
for($row = 0; $row < 1; $row++) {
for ($col = 0; $col < 6; $col++) {
$tableopenorders .= "<td>".$decodedopenorders[$element][$row][$col]."</td>";
}
}
$tableopenorders .= "</tr>";
}
$tableopenorders .= "</table>";
There's a maximum of "count($decodedopenorders)" $elements, max. 1 $row and 6 rows in the $decodedopenorders array. The iterator starts a 0, so I used <.
Why does this not work?

When you loop through your arrays you have changed the key to be something other than the typical 0, 1, 2, 3. When you change the key the $decodedopenorders[0] no longer works and instead you would have to call $decodedopenorders['BTC_YACC']; So here is the code I got to work:
$decodedopenorders = array (
'BTC_YACC' => array (
0 => array (
'orderNumber' => '3585379',
'type' => 'sell',
'rate' => '0.0001',
'amount' => '128',
'total' => '0.0128',
'date' => '2014-05-18 08:54:37')
)
);
$tableopenorders = "<table><th>OrderID</th><th>Type</th><th>Rate</th><th>Amount</th><th>Total in BTC</th><th>Date placed</th><tr>";
foreach ($decodedopenorders as $element => $value) {
$tableopenorders .= "<tr>";
foreach ($decodedopenorders[$element] as $row => $value){
foreach ($decodedopenorders[$element][$row] as $order) {
$tableopenorders .= "<td>". $order ."</td>";
}
}
$tableopenorders .= "</tr>";
}
$tableopenorders .= "</table>";
echo $tableopenorders;

Related

how to sum in a multidimensional array in php

As an example I have an array like this:
$Batches = array(
$Batch_1= array(
$A_Row= array(1,1,0,0),
$B_Row = array(0,0,0,1),
$C_Row = array(0,0,0,1)),
$Batch_2= array(
$A_Row= array(1,0,0,0),
$B_Row = array(0,0,0,1),
$C_Row = array(0,0,0,1))
);
I want to sum per each $n_Row:
So I should get a result like this:
$Sum_Array = array(
$A_row=array(2,1,0,0),
$B_row= array(0,0,0,2),
$C_row = array(0,0,0,2)
);
But I'm having difficulty trying to get this result and need some tips/advice from someone else.
This is my code so far:
//count rows and columns
$count_array= count($Batches);
$count_row = count($Batches[0]);
$count_column = count($Batches[0][0]);
$Array_sum = array();
for($array=0;$array<$count_array;$array++){
for($row=0;$row<$count_row;$row++){
for($col=0;$col<$count_column;$col++){
//echo $Batches[$array][$row][$col] . "\n";
if($Batches[$array][$row][$col]==1){
$Batches[$array][$row][$col]++;
}
$Array_sum[]=$Batches[$array][$row][$col];
}
}
}
Anyone who can help me in the right direction?
Thanks in advance.
I think your "array"
$Batches = array(
$Batch_1= array(
$A_Row= array(1,1,0,0),
$B_Row = array(0,0,0,1),
$C_Row = array(0,0,0,1)),
$Batch_2= array(
$A_Row= array(1,0,0,0),
$B_Row = array(0,0,0,1),
$C_Row = array(0,0,0,1))
);
is a product of the imagination. But it is also valid PHP code. I assume you want to work with keys and the array looks like this:
$Batches = array(
'Batch_1' => array(
'A_Row' => array(1,1,0,0),
'B_Row' => array(0,0,0,1),
'C_Row' => array(0,0,0,1)),
'Batch_2' => array(
'A_Row' => array(1,0,0,0),
'B_Row' => array(0,0,0,1),
'C_Row' => array(0,0,0,1))
);
The Summation works better with foreach.
$sum_arr = [];
foreach($Batches as $ib => $batch){
foreach($batch as $ir => $row){
foreach($row as $ic => $col){
$sum_arr[$ir][$ic] ??= 0;
$sum_arr[$ir][$ic] += $col;
}
}
}
var_export($sum_arr);
The Output:
array (
'A_Row' =>
array (
0 => 2,
1 => 1,
2 => 0,
3 => 0,
),
'B_Row' =>
array (
0 => 0,
1 => 0,
2 => 0,
3 => 2,
),
'C_Row' =>
array (
0 => 0,
1 => 0,
2 => 0,
3 => 2,
),
)
The summation also works with the original array. However, this array has only numeric keys.

How to use nested loop in this example?

Consider the following $data array:
Array
(
[0] => Array
(
[code] => 20
[name] => Name 1
[month] => 4
[cost] => 100
..
..
)
[1] => Array
(
[code] => 30
[name] => Name 2
[month] => 3
[cost] => 120
..
..
)
[1] => Array
(
[code] => 30
[name] => Name 2
[month] => 6
[cost] => 180
..
..
)
..
..
)
Each array can have unknown number of codes. Each code has a different month ID. I want to sort and display the data so that there is just one row for the each code, and then in that row, display the value of the [cost] in the column number equal to the month. For example:
Column 1 2 3 4 5 6 7 8 9 10 11 12
Name 1 100
Name 2 120 180
Here's what I'm trying:
In order to find out how many rows should be printed, I fetch the unique code values:
$codes = array();
foreach( $data as $row ){
if ( in_array($row['code'], $codes) ) {
continue;
}
$codes[] = $row['code'];
}
Next, I use a loop to print the rows:
foreach( $codes as $code ){
//print 12 columns for each othe row
for ($i = 1; $<=12; $i++) {
//display column value if the code is same as the row
//and the month value is same as $i
//here's the problem
if (( $data['code'] == $code ) &&( $data['month'] == $i )) {
echo $data['cost'];
}
}
}
Problem/Question:
Do I need to put another loop inside the for loop to check if the $data['code'] == $code ? Or how can I do that?
I would use one loop to re-index the array:
$list = $codes = [];
for ($array as $item){
$list[$item['code']][$item['month']] = $item;
$codes[$item['code']] = $item['name'];
}
then use two loops to print:
for ($codes as $code => $codeName){
echo '<tr><th>', $codeName, '</th>';
for (range(1, 12) as $month){
echo '<td>', ($list[$code][$month]['cost'] ?? ''), '</td>;
}
echo '</tr>', "\n";
}
I really do not like the idea of if()s inside the loops.
I would suggest that you preprocess your data to a structured array first and then you print it, for example, indexed by code with a structure like:
[
['the code'] => [
'name' => '',
'months' => [
'6' => // cost
]
]
]
You can do it like this:
$items = [
[
'code' => 20,
'name' => 'Name 1',
'month' => 4,
'cost' => 100,
],
[
'code' => 30,
'name' => 'Name 2',
'month' => 3,
'cost' => 120,
],
[
'code' => 30,
'name' => 'Name 2',
'month' => 6,
'cost' => 180,
],
];
$sortedItems = [];
foreach ($items as $item) {
if (!isset($sortedItems[$item['code']])) {
$sortedItems[$item['code']] = [
'name' => $item['name'],
'months' => [],
];
}
$sortedItems[$item['code']]['months'][$item['month']] = $item['cost'];
}
You can the print it using a function similar to this:
function printItemsOf(array $list) {
echo '<table>';
// print header
echo '<tr>';
echo '<td>Column</td>';
for ($i = 1; $i <= 12; $i++) {
echo '<td>' . $i . '</td>';
}
echo '</tr>';
// print items
foreach ($list as $code => $item) {
echo '<tr>';
echo '<td>' . $item['name'] . '</td>';
for ($i = 1; $i <= 12; $i++) {
if (!isset($item['months'][$i])) {
echo '<td></td>';
} else {
echo '<td>' . $item['months'][$i] . '</td>';
}
}
echo '</tr>';
}
echo '</table>';
}
Which outputs:
<table border="1"><tr><td>Column</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td><td>11</td><td>12</td></tr><tr><td>Name 1</td><td></td><td></td><td></td><td>100</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>Name 2</td><td></td><td></td><td>120</td><td></td><td></td><td>180</td><td></td><td></td><td></td><td></td><td></td><td></td></tr></table>

Group 2d array by column value and concatenate values within each group

I have a simple php array for location postcode and their name. I want compress 'code' by 'name'. This code from WooCommerce database zones.
$new_arr = [
[
'name' => 'Jambi Selatan',
'code' => '36139',
'code_name' => '36139 - Jambi Selatan'
],
[
'name' => 'Jambi Selatan',
'code' => '36137',
'code_name' => '36137 - Jambi Selatan'
],
[
'name' => 'Bagan Pete',
'code' => '36129',
'code_name' => '36129 - Bagan Pete'
],
[
'name' => 'Bagan Pete',
'code' => '36127',
'code_name' => '36127 - Bagan Pete'
]
];
I want get final result combined by 'name' and 'code' like this: i try array_unique method but not working.
Array (
[0] => Array
(
[name] => Jambi Selatan
[code] => 36139, 36137
[code_name] => 36139, 36139 - Jambi Selatan
)
[1] => Array
(
[name] => Bagan Pete
[code] => 36127, 36129
[code_name] => 36127, 36129 - Bagan Pete
)
)
I try this method, but not fix at 'code_name'
$out = array();
foreach ($new_arr as $key => $value){
if (array_key_exists($value['name'], $out)){
$out[$value['name']]['code'] .= ', '.$value['code'];
} else {
$out[$value['name']] = array(
'name' => $value['name'],
'code' => $value['code'],
'code_name' => $value['code'] . ' - ' . $value['name']
);
}
}
$out = array_values($out);
print_r($out);
You have to check duplicate name by in_array and update exist array value .If not exist insert that value to $out array .
$out = array();
foreach($new_arr as $k=>$v) {
//empty array state
if(count($out) == 0) {
$out[] = $v;
continue;
}
foreach ($out as $key => $value) {
if(in_array($v["name"],$value)) {
$out[$key]["code"] .= ",".$v["code"];
//for the code_name output as OP described
$nn = explode("-", $value["code_name"]);
$l = count($nn) - 1;
unset($nn[$l]);
$out[$key]["code_name"] = implode($nn).",".$v["code_name"];
break;
} else {
if((count($out)-1) == $key) {
$out[] = $v;
}
}
}
}
var_dump($out);
For someone have problem like me, this method for fix it:
$out = array();
foreach ($new_arr as $key => $value){
if (array_key_exists($value['name'], $out)){
$out[$value['name']]['code'] .= ', '.$value['code'];
$out[$value['name']]['code_name'] .= ', '.$value['code'] . ' - ' . $value['name'];
} else {
$out[$value['name']] = array(
'name' => $value['name'],
'code' => $value['code'],
'code_name' => $value['code']
);
}
}
$out = array_values($out);
print_r($out);
Final result;
Array
(
[0] => Array
(
[name] => Jambi Selatan
[code] => 36139, 36137
[code_name] => 36139, 36137 - Jambi Selatan
)
[1] => Array
(
[name] => Bagan Pete
[code] => 36129, 36127
[code_name] => 36129, 36127 - Bagan Pete
)
)
Please try below one as another approach:
<?php
$arr = Array (
Array
(
'name' => 'Jambi Selatan',
'code' => '36139',
'code_name' => '36139 - Jambi Selatan'
),
Array
(
'name' => 'Jambi Selatan',
'code' => '36137',
'code_name' => '36137 - Jambi Selatan'
),
Array
(
'name' => 'Bagan Pete',
'code' => '36129',
'code_name' => '36129 - Bagan Pete'
),
Array
(
'name' => 'Bagan Pete',
'code' => '36127',
'code_name' => '36127 - Bagan Pete'
)
);
$newarr = array();
$finalArr = array();
foreach($arr as $aa) {
$newarr[$aa['name']][] = $aa;
}
foreach($newarr as $kk => $bb) {
foreach($bb as $cc) {
$finalArr[$kk]['name'] = $cc['name'];
if(isset($finalArr[$kk]['code'])) {
$finalArr[$kk]['code'] = $finalArr[$kk]['code'].','.$cc['code'];
} else {
$finalArr[$kk]['code'] = $cc['code'];
}
if(isset($finalArr[$kk]['code_name'])) {
$finalArr[$kk]['code_name'] = $finalArr[$kk]['code_name'].','.$cc['code_name'];
} else {
$finalArr[$kk]['code_name'] = $cc['code_name'];
}
}
}
echo "<pre>";
print_r($finalArr);
echo "</pre>";
?>
Definitely avoid any suggestions that use more than one loop to group and concatenate the data.
I do endorse #Opsional's snippet. An alternative approach is to push reference variables into the result array, then only concatenate comma-separated values to the appropriate reference variable.
Code: (Demo)
$result = [];
foreach ($arr as $row) {
if (!isset($ref[$row['name']])) {
$ref[$row['name']] = $row;
$result[] = &$ref[$row['name']];
} else {
$ref[$row['name']]['code'] .= ', ' . $row['code'];
$ref[$row['name']]['code_name'] .= ', ' . $row['code_name'];
}
}
var_export($result);
For any purist developers that insist on destroying references, call unset($ref) after the loop.
Here is a streamlined version of #Opsional's snippet: (Demo)
$result = [];
foreach ($arr as $row) {
if (!isset($result[$row['name']])) {
$result[$row['name']] = $row;
} else {
$result[$row['name']]['code'] .= ', ' . $row['code'];
$result[$row['name']]['code_name'] .= ', ' . $row['code_name'];
}
}
var_export(array_values($result));

Count array key that contain specific string

I have an array like that contain key with same name but with number at the end
array example:
Array
(
[field_name0] => name
[field_name1] => sku_package_height
[field_name2] => sku_package_width
[custom_field] => 13
[attribute] => 'test'
[field_name3] => sku_package_length
[field_name4] => sku_package_weight
)
from the example above i want to count how many record that has array key that contain field_name, so the result I want will be 5
you can do this :
$count = 0;
foreach($array as $key => $value){
if(strpos($key,"field_name") > -1){
$count++;
}
}
$count will have number of keys.
You can do it like below:-
<?php
$original_array = Array
(
'field_name0' => 'name',
'field_name1' => 'sku_package_height',
'field_name2' => 'sku_package_width',
'custom_field' => 13,
'attribute' => 'test',
'field_name3' => 'sku_package_length',
'field_name4' => 'sku_package_weight'
);
$search = "field_name";
$counter = 0;
foreach($original_array as $key=> $value){
if(strstr($key,$search)){
$counter = $counter+1;
}
}
echo $counter;
Output:-https://eval.in/704506
Or
<?php
$original_array = Array
(
'field_name0' => 'name',
'field_name1' => 'sku_package_height',
'field_name2' => 'sku_package_width',
'custom_field' => 13,
'attribute' => 'test',
'field_name3' => 'sku_package_length',
'field_name4' => 'sku_package_weight',
);
$search = "field_name";
$counter = 0;
foreach($original_array as $key=> $value){
if(is_numeric(strpos($key,$search))){
$counter = $counter+1;
}
}
echo $counter;
Output:-https://eval.in/704518
Check the isnumeric of the string position "field_name" in key
$i= 0;
foreach($arrayfields as $keys => $values){
if (is_numeric(strpos($keys,"field_name"))){
$i++;
}
}
echo $i;
<?php
$array=array("field_name0"=>"name","field_name1"=>"sku_package_height ","field_name2"=>"sku_package_width","custom_field"=>"13","attribute"=>"test","field_name3"=>"sku_package_length", "field_name4"=>"sku_package_weight");
echo $arraykey= count(preg_grep("/^field_name(\d)+$/",array_keys($array)));
?>

Multidimensional array looping (PHP) - a better way?

Is there a better/more efficient way to loop through this data?
I need to loop through the array data with the 'Name' first and the 'ListID' second but the external API request generates the array as per the code below (the other way round).
// Array Data
$csList = array(
array(
'ListID' => 'BGERFwQTrHoseE4sweebqwyAxuJ9YU',
'Name' => 'Monthly Newsletter Subscribers'
),
array(
'ListID' => 'kHdUQMbELgMyojuATz9Dsbxz3WViVo',
'Name' => 'Special Mailout'
)
);
// Generate Array Varaibles
foreach($csList as $array => $values) {
foreach($values as $k => $v) {
for($i = 1; $i < count($csList); $i++) {
$csListData[$k][] = $v;
}
}
}
// Loop Data
for($i = 0; $i < count($csList); $i++) {
echo $csListData['Name'][$i].'<br>';
echo $csListData['ListID'][$i].'<br>';
}
It's not at all clear why you're rearranging the data. Loop over the array and access whatever keys you want in whatever order you want.
$csList = array(
array(
'ListID' => 'BGERFwQTrHoseE4sweebqwyAxuJ9YU',
'Name' => 'Monthly Newsletter Subscribers'
),
array(
'ListID' => 'kHdUQMbELgMyojuATz9Dsbxz3WViVo',
'Name' => 'Special Mailout'
)
);
foreach ($csList as $item) {
echo $item['Name'].'<br>';
echo $item['ListID'].'<br>';
}
Your inner for loop is useless. You can use the $array key to get your array as wanted :
foreach($csList as $array => $values) {
foreach($values as $k => $v) {
$csListData[$k][$array] = $v;
}
}
// Loop Data
for($i = 0, $c = count($csList); $i <$c; $i++) {
echo '<br>';
echo $csListData['Name'][$i].'<br>';
echo $csListData['ListID'][$i].'<br>';
}
Also, moving the count() out of the check will avoid to count at every iteration of the loop.
// Array Data
$csList = array(
array(
'ListID' => 'BGERFwQTrHoseE4sweebqwyAxuJ9YU',
'Name' => 'Monthly Newsletter Subscribers'
),
array(
'ListID' => 'kHdUQMbELgMyojuATz9Dsbxz3WViVo',
'Name' => 'Special Mailout'
)
);
You can do as follow:
$newCsList = array();
$newCsList = array_map(function ($val){
return array_reverse($val,true);
},$csList);
The result is like:
**Array (
[0] => Array (
[Name] => Monthly Newsletter Subscribers
[ListID] => BGERFwQTrHoseE4sweebqwyAxuJ9YU
)
[1] => Array (
[Name] => Special Mailout
[ListID] => kHdUQMbELgMyojuATz9Dsbxz3WViVo
)
)**
But for taking each element you can do:
$newCsList = array();
$newCsList = array_map(function ($val){
$my_test_ary = array_reverse($val);
echo $my_test_ary['Name'].'<br/>'.$my_test_ary['ListId'];
},$csList);

Categories