PHP fill the missing values with empty values in an array - php

I have the array like
array(
[0] => array(
[a] => r1,
[b] => c1,
[c] => d1,
),
[1] => array(
[a] => r1,
[b] => c1,
[c] => d2,
),
[2] => array(
[a] => r1,
[b] => c1,
[c] => d3,
),
[3] => array(
[a] => r1,
[b] => c2,
[c] => d1,
),
[4] => array(
[a] => r1,
[b] => c2,
[c] => d3,
),
[5] => array(
[a] => r1,
[b] => c3,
[c] => d1,
)
)
Currently I am getting the output like
-------------------------------------
| C1,D1 | C1,D2 | C1,D3 |
-------------------------------------
| C2,D2 | C3,D1 | - |
-------------------------------------
| - | - | - |
-------------------------------------
But I need the output must be displayed by 3x3 matrix Like
-------------------------------------
| C1,D1 | C1,D2 | C1,D3 |
-------------------------------------
| - | C2,D2 | - |
-------------------------------------
| C3,D1 | - | - |
-------------------------------------
Please help me to fill the missing values with empty values
My code :
for($i=1; $i<=3; $i++){
for($j=1; $j<=3; $j++){
for($r=0; $r<9; $r++){
if(isset($rows[$r]) && $rows[$r]['b'] == 'C'.$i && $rows[$r]['c'] == 'D'.$j) {
//Store data to array
$data[] = array(
'a' => $rows[$r]['a'],
'b' => $rows[$r]['b'],
'c' => $rows[$r]['c']
);
}
}
}
}

Option => Fill the array with empty values then fill in the values you got.
Option => Remember which index positions you fill and then fill the rest by excluding the ones u filled.
Number 1 is easier.
Number 2 has better performance.
You can use array_fill
or do a loop through the array:
for( $i = 0 ; $i < MAX ; $i++ )
arr[i] = ""; // fill with whatever value you like

Related

Why is my recursive function not working when used within a loop?

I have a database that stores how users were referred into the system like so:
| user_id | referrer_id |
| 3 | 2 |
| 4 | 3 |
| 5 | 3 |
| 6 | 4 |
| 7 | 4 |
| 8 | 5 |
| 9 | 5 |
| 10 | 6 |
| 11 | 10 |
| 12 | 10 |
and I would like to display a specific user's network, i.e., the user, the other users which s/he referred directly, and also other users referred by the direct referrals, in an array.
So far, I've been able to create a recursive function
// The actual get_downlines() function
function get_downlines($upline_id) {
// Init the UsersMatrix model
$um_model = model('UsersMatrix');
$um_model->select('user_id')->where('upline_id', $upline_id);
$downlines_check = $um_model->findAll(5);
$downlines = [];
if ( ! empty($downlines_check) ) {
foreach($downlines_check as $check) {
$downlines[] = $check->user_id;
}
}
return $downlines;
}
// User to check
$user = 3;
// The initial network array
$network_array['user_network'][0] = [
'id' => $user,
'text' => "user-$user"
];
// Get the user's network
function get_network($referrer, $network_array){
// This function basically runs a SELECT user_id FROM users WHERE referrer_id = $referrer_id
// and returns the user_ids in an array: get_downlines()
$downlines = get_downlines($referrer);
if (count($downlines) > 0){
// Loop through the downlines
foreach($downlines as $downline){
// Update the array
array_push($network_array['user_network'], [
'id' => $downline,
'text' => "user-$downline",
]);
// Check for the downlines of this user and inner levels
get_network($downline, $network_array);
}
}
// Return the network array
return $network_array;
}
With this, I expect that when I run the get_network(3, $network_array);, I should get an array like so:
Array
(
[user_network] => Array
(
[0] => Array
(
[id] => 3
[text] => user-3
),
[1] => Array
(
[id] => 4
[text] => user-4
),
[2] => Array
(
[id] => 5
[text] => user-5
),
[3] => Array
(
[id] => 6
[text] => user-6
),
[4] => Array
(
[id] => 7
[text] => user-7
),
[5] => Array
(
[id] => 8
[text] => user-8
),
[6] => Array
(
[id] => 9
[text] => user-9
),
[7] => Array
(
[id] => 10
[text] => user-10
)
)
)
instead, the page dies with a maximum execution time error. But if I use a user ID without an indirect referrer, it works well. E.g user id 10.
Where am I going wrong?

How to execute that in 1 query?

I have 2 tables customer and orders:
customers:
| custID | Name | Age |
|--------|-------|-----|
| 1 | Peter | 23 |
| 2 | Julie | 34 |
| 3 | Tom | 45 |
orders:
| custID | product | color |
|--------|---------|-------|
| 1 | shirt | blue |
| 1 | jacket | black |
| 2 | jacket | green |
| 3 | hat | grey |
| 3 | shirt | white |
I now want to get all customers and their orders, ordered as a list. So something like that:
Array
(
[0] => Array
(
[ID] => 1
[name] => Peter
[age] => 23
[orders] => Array
(
[0] => Array
(
[product] => shirt
[color] => blue
)
[1] => Array
(
[product] => jacket
[color] => black
)
)
)
[1] => Array
(
[ID] => 2
[name] => Julie
[age] => 34
[orders] => Array
(
[0] => Array
(
[product] => jacket
[color] => green
)
)
)
[2] => Array
(
[ID] => 3
[name] => Tom
[age] => 45
[orders] => Array
(
[0] => Array
(
[product] => hat
[color] => grey
)
[1] => Array
(
[product] => shirt
[color] => white
)
)
)
)
When I do:
SELECT name, age, product, color
FROM `customers`, `orders`
where `customers`.`id` = `orders`.id
group by name
I get:
| name | age | product | color |
|-------|-----|---------|-------|
| Peter | 23 | jacket | green |
| Julie | 34 | shirt | blue |
| Tom | 45 | hat | grey |
Is this even possible with only one query?
You could simply make the query below:
SELECT *
FROM customers
JOIN orders
USING custID
GROUP BY Name
ORDER BY custID ASC;
A couple of steps here...
First, you should run the following query:
SELECT
`customers`.`id`,
`customers`.`name`,
`customers`.`age`,
`orders`.`product`,
`orders`.`color`
FROM `customers`, `orders`
where `customers`.`id` = `orders`.`id`
order by `customers`.`id`
Which should give you de-normalized tabular data that looks something like this:
$array = array(
array("id" => 1, "name" => "Peter", "age" => 23, "product" => "shirt", "color" => "blue"),
array("id" => 1, "name" => "Peter", "age" => 23, "product" => "jacket", "color" => "black"),
array("id" => 2, "name" => "Julie", "age" => 34, "product" => "jacket", "color" => "green"),
array("id" => 3, "name" => "Tom", "age" => 45, "product" => "hat", "color" => "grey"),
array("id" => 3, "name" => "Tom", "age" => 45, "product" => "shirt", "color" => "white")
);
You can then transform the that data into your desired format as follows:
$transformed = array();
$i = 0;
while ($i < count($array)) {
$id = $array[$i]["id"];
$name = $array[$i]["name"];
$age = $array[$i]["age"];
$products = array();
while ($i < count($array) && $id == $array[$i]["id"]) {
array_push($products, array("product" => $array[$i]["product"], "color" => $array[$i]["color"]));
$i++;
}
array_push($transformed, array("id" => $id, "name" => $name, "age" => $age, "products" => $products));
}
http://sandbox.onlinephpfunctions.com/code/6fe856e1f71f699e84215b6f66d25589f71e255e
i think you should user INNER JOIN:
SELECT * FROM customers AS c INNER JOIN orders AS o ON c.custID = o.custID GROUP BY c.custID ORDER BY c.custID ASC;
There is no point in trying to achieve the desired outcome with single query. With the first query get the list of customers. Then perform a second query, which will load all the orders for the customers from the first query. And in a loop match orders to respective customers.
EDIT: something like this
$result = [];
$customers = $pdo->query("SELECT * FROM `customers`")->fetchAll();
foreach ($customers as $c) {
$result[$c['id']] = $c;
}
$orders = $pdo->query("SELECT * FROM `orders` WHERE `custID` IN (".implode(', ', array_keys($result).")");
foreach ($orders as $o) {
if (!isset($result[$o['custId']]['orders']))
$result[$o['custId']]['orders'] = [];
$result[$o['custId']]['orders'][] = $o;
}
Your sql SELECT name, age, product, color FROMcustomers,orderswherecustomers.id=orders.id group by name is fine, just add the customer id and order id also in the sql. Then, in PHP, as you iterate the result set, populate the customer info first (id, name, age) with customer id as the key and name, age as value as an array. Likewise, populate the order for that customer in the key 'orders' with the order id as key and value as an array (product, color).
Once you have the array populated, iterate over that array and keep putting things into a new array since the output you want is an array with sequential keys (0, 1, 2 etc) instead of customer id.
$initialList = array();
while($row = $result->fetch_assoc()) {
if(!array_key_exists($row['customer_id'], $initialList)) {
$initialList[$row['customer_id']] = array(
'name' => $row['name'],
'age' => $row['age'],
'orders' => array()
);
}
$initialList[$row['customer_id']]['orders'][] = array(
'product' => $row['product'],
'color' => $row['color']
);
}
$finalList = array();
foreach($initialList as $customerId => $customer) {
$customer['ID'] = $customerId;
$finalList[] = $customer;
}
//to print and check the array
print_r($finalList);
try this:
SELECT c.custID,c.name, c.age, group_concat(CONCAT_WS(':',o.product,o.color)SEPARATOR ',') as productos
FROM customers AS c
INNER JOIN orders AS o ON c.custID = o.custID
GROUP BY c.custID;
You just have to parse the products.
$array=array();
while($r = $res->fetch_assoc()) {
$id=$row['custID'];
$name=$row['name'];
$age=$row['age'];
$productos=$row['productos'];
$productsSeparats = explode(',',$productos);
$orders=array();
foreach ($productsSeparats as $value) {
$ar=explode(':',$value);
array_push($orders, array("product" => $ar[0], "color" => $ar[1]));
}
array_push($array, array("id" => $id, "name" => $name, "age" => $age, "orders" => $orders));
}

How to generate matrix from dynamic multidimensional array in php

I have multidimensional array as below where cid as an option and values are defined as its attributes. Such array is generating based on selection from O1, O2, O3 and so on.
Array
(
[0] => Array
(
[cid] => O1
[values] => Array
(
[0] => O1A1
[1] => O1A2
)
)
[1] => Array
(
[cid] => O2
[values] => Array
(
[0] => O2A1
[1] => O2A2
[2] => O2A3
)
)
)
Now I need to generate a matrix in HTML table as below:
+--------+------------+-----------------------------+
| O1 | O2 | Some other columns |
+--------+------------+-----------------------------+
| O1A1 | O2A1 | Some other column values |
| O1A1 | O2A2 | Some other column values |
| O1A1 | O2A3 | Some other column values |
| O1A2 | O2A1 | Some other column values |
| O1A2 | O2A2 | Some other column values |
| O1A2 | O2A3 | Some other column values |
+--------+------------+-----------------------------+
There are total 6 rows ( creating like 2 X 3 (option O1 and O2 values)). I have tried with nested for..loop but array have dynamic values ( it is based on selection).
Thanks in advance for any help.
Here is the solution :)
<?php
$input = array(0 => array('cid' => 'O1', 'values' => array (0 => 'O1A1',1 => 'O1A2')), 1 => array('cid' => 'O2', 'values' => array (0 => 'O2A1', 1 => 'O2A2', 2=>'O2A3')));
echo "<pre>"; print_r($input);
///make an array of matrix
$matrixArr =array();
for( $i= 0; $i< 2; $i++ )
{
for( $j=0; $j <3; $j++ )
{
$matrixArr[$input[0]['values'][$i]][]= $input[1]['values'][$j];
}
}
echo "<pre>"; print_r($matrixArr);
///now print that array
foreach($matrixArr as $key =>$val)
{
foreach($val as $v)
{
echo $key." | ".$v.' | Some other column values </br>';
}
?>
you will get this
O1A1 | O2A1 | Some other column values
O1A1 | O2A2 | Some other column values
O1A1 | O2A3 | Some other column values
O1A2 | O2A1 | Some other column values
O1A2 | O2A2 | Some other column values
O1A2 | O2A3 | Some other column values
Sir, check this one, if it is helpful for you ...
<?php
$input = array(
0 => array(
'cid' => 'O1',
'values' => array (0 => 'O1A1',1 => 'O1A2', 2=>'01A3',3=>'01A4')),
1 => array(
'cid' => 'O2',
'values' => array (0 => 'O2A1', 1 => 'O2A2', 2=>'O2A3',3=>'O2A4',4=>'O2A5'))
);
$matrixArr =array();
for( $i= 0; $i < count($input[0]['values']); $i++ )
{
for( $j=0; $j < count($input[1]['values']); $j++ )
{
$matrixArr[$input[0]['values'][$i]][]= $input[1]['values'][$j];
}
}
foreach($matrixArr as $key =>$val)
{
foreach($val as $v)
{
echo $key." | ".$v.' | Some other column values </br>';
}
}
?>

PHP Display an array in table format

I have an array like below, I need to display that array into table. I have tried the function using PHP but it getting rows and cells value, I need three type of values:
Rows name
Columns name
name for the corresponding row and column
Note : I have convert the below array1 into array 2
Array 1 :
Array
(
[0] => Array ([id] => 1[rows] => R1[columns] => c1[name] => 1)
[1] => Array([id] => 2[rows] => R1[columns] => c2[name] => 2)
[2] => Array([id] => 3[rows] => R1[columns] => c3[name] => 3)
[3] => Array([id] => 4[rows] => R2[columns] => c1 [name] => 1)
[4] => Array([id] => 5[rows] => R2[columns] => c2[name] => 2)
[5] => Array([id] => 6[rows] => R2[columns] => c3[name] => 3)
)
Array 2 :
Array
(
[0] => Array([0] => R1[1] => c1[2] => 1)
[1] => Array([0] => R1[1] => c2[2] => 2)
[2] => Array([0] => R1[1] => c3[2] => 3)
[3] => Array([0] => R2[1] => c1[2] => 1)
[4] => Array([0] => R2[1] => c2[2] => 2)
[5] => Array([0] => R2[1] => c3[2] => 3)
)
Table :
id | row | column | value
--------------------------
1 | r1 | c1 | 1
2 | r1 | c2 | 2
3 | r1 | c3 | 3
4 | r2 | c1 | 1
5 | r2 | c2 | 2
6 | r2 | c3 | 3
Function : This function convert the array2 into table
function convetTable($array) {
$rows = array();
$rows[0] = array();
foreach ($array as $column) {
if (!in_array($column[1],$rows[0])) {
$rows[0][] = $column[1];
}
}
$count = count($rows[0]);
foreach ($array as $row) {
$rowTtl = $row[0];
$rowQty = $row[1];
$rowVal = $row[2];
if (!isset($rows[$rowTtl])) $rows[$rowTtl] = array_pad(array(),$count,0);
$rows[$rowTtl][array_search($rowQty,$rows[0])] = $rowVal;
}
return $rows;
}
$table = convetTable($array2);
HTML :
{foreach from=$table item=key key=foo}
<tr class="prototype" id="first_row">
<td>Remove Row
<td><input type="text" name="rows[]" value="{$foo}" class="number" /></td>
{foreach from=$key item=cell}
<td align="center"><input type="text" name="cols[]" value="{$cell}" class="id number" /></td>
{/foreach}
</tr>
{/foreach}
Expected OutPut
0 C1 C2 C3
R1 1 2 3
R2 1 2 3
PS : here c1,c2,c3,1,2,3 are $cell value.
What I try to display $row,$col,$name, but here I'm getting $row and $cell only.
I need another value name for the corresponding row and column.
try this..
$count = count($array); //this will give you the count of elements of your array...
echo "<table border="1"><tr><th>ID</th><th>ROWS</th><th>COLUMNS</th><th>NAMES</th></tr>";
for($i=1;$i<=$count;$i++) //loop through the array..
{
echo "<tr><td>$i</td><td>".$array[$i][0]."</td><td>".$array[$i][1]."</td><td>".$array[$i][2]."</td></tr>";
}
echo "</table>";
Please note this code is to show you how to simplify your massiave code... may be you will need to edit this code to get the desired output...

How to retrieve tree nodes children (recursive function help)

I have a binary, the database table of relationships looks like this:
+----+----------+---------+-----+
| id | parentID | childID | pos |
+----+----------+---------+-----+
| 1 | 1 | 2 | l |
| 2 | 1 | 3 | r |
| 3 | 2 | 4 | l |
| 4 | 3 | 5 | r |
| 5 | 4 | 6 | l |
| 6 | 5 | 7 | r |
+----+----------+---------+-----+
I am able to extract or children of for example 1 - but I have very clumsy function for that, so I need something that works better.
The output I need should look like this:
Array
(
[0] => Array
(
[id] => 2
[parentID] => 1
[pos] => l
)
[1] => Array
(
[id] => 4
[parentID] => 2
[pos] => l
)
[2] => Array
(
[id] => 6
[parentID] => 4
[pos] => l
)
[3] => Array
(
[id] => 3
[parentID] => 1
[pos] => r
)
[4] => Array
(
[id] => 5
[parentID] => 3
[pos] => r
)
[5] => Array
(
[id] => 7
[parentID] => 5
[pos] => r
)
)
So far I came up with this function, however it returns nested array, I want it flattened ... but whenever I tried it it just fails.
function children($pid) {
//set sql
$sql = "SELECT * FROM relationships WHERE parentID = ".$pid;
//save query to result
$result = mysql_query ($sql)
or die("Bad request " . mysql_error());
while ($item = mysql_fetch_array($result)):
$topchild["id"] = $item["childID"];
$topchild["parentID"]= $item["parentID"];
$topchild["pos"] = $item["pos"];
$children[] = $topchild;
$children[] = children($item["childID"]);
endwhile;
return $children;
}
What do I do wrong there?
I want it flattened
$children[] = children($item["childID"]);
instead add each of the items in the return value separately:
foreach (children($item['childID'] as $child)
$children[]= $child;
(Also shouldn't $topchild be initialised inside the loop?)
If you are doing a lot of recursive queries like this, a parent-child relation table is not a good choice of data structure. Consider one of the hierarchically-oriented solutions such as nested sets.

Categories