How to format an associative array with another structure? - php

I have a query like this:
select truck, oil_type, km_min, km_max from trucks;
I'm using codeigniter and with the $query->result_array() function so its loaded in an associative array with this structure:
/*
array(
truck
oil_type
km_min
km_max
)
*/
$arr[0]["truck"] = 2;
$arr[0]["oil_type"] = 2;
$arr[0]["km_min"] = 345;
$arr[0]["km_max"] = 567;
$arr[1]["truck"] = 2;
$arr[1]["oil_type"] = 4;
$arr[1]["km_min"] = 234;
$arr[1]["km_max"] = 867;
$arr[2]["truck"] = 1;
$arr[2]["oil_type"] = 2;
$arr[2]["km_min"] = 545;
$arr[2]["km_max"] = 867;
$arr[3]["truck"] = 4;
$arr[3]["oil_type"] = 3;
$arr[3]["km_min"] = 45;
$arr[3]["km_max"] = 567;
Then, I'm trying to restructure it grouping the trucks by the id, something like this:
/*
trucks - array(
truck
truck_data - array(
oil_type
km_min
km_max
)
)
*/
$arr["truck"][0]= 2;
$arr["truck"][0]["truck_data"][0]["oil_type"] = 2;
$arr["truck"][0]["truck_data"][0]["km_min"] = 345;
$arr["truck"][0]["truck_data"][0]["km_max"] = 567;
$arr["truck"][0]["truck_data"][1]["oil_type"] = 4;
$arr["truck"][0]["truck_data"][1]["km_min"] = 234;
$arr["truck"][0]["truck_data"][1]["km_max"] = 867;
$arr["truck"][1]= 1;
$arr["truck"][1]["truck_data"][0]["oil_type"] = 2;
$arr["truck"][1]["truck_data"][0]["km_min"] = 545;
$arr["truck"][1]["truck_data"][0]["km_max"] = 867;
$arr["truck"][2]= 4;
$arr["truck"][2]["truck_data"][0]["oil_type"] = 3;
$arr["truck"][2]["truck_data"][0]["km_min"] = 45;
$arr["truck"][2]["truck_data"][0]["km_max"] = 567;
I thought in something like the code below:
$res = $query->result_array();
$cnt_total = count($res);
$y = 0;
for ($x=0; $x < $cnt_total -1 ; $x++) {
$truck = $res[$x]["truck"];
$trucks["truck"][$y] = $truck;
$q = $x + 1;
$i = 0;
do{
$trucks[$y][$i]["oil_type"] = $res[$q]["oil_type"];
$trucks[$y][$i]["km_min"] = $res[$q]["km_max"];
$trucks[$y][$i]["km_max"] = $res[$q]["km_max"];
$q++;
$i++;
if ($q <= $cnt_total) break;
} while ( $truck === $res["truck"][$q] );
$y++;
}
But does not work properly... I'm too far of the solution? The performance It's important for me in this particular case.
There is a phpfiddle where you can try:
http://phpfiddle.org/main/code/67j-ui5
Any idea, tip, or advice will be appreciated, and if you need more info, let me know and I'll edit the post.

Try this:
$res = $query->result_array();
$trucks = array();
foreach ($res as $row) {
$truck["truck"] = $row["truck"];
$truck["truck_data"] = array(
'oil_type' => $row["oil_type"],
'km_min' => $row["km_min"],
'km_max' => $row["km_max"],
);
$trucks[] = $truck;
}
var_dump($trucks);

What you've provided as a desired result is a little ambiguous. This might give what you're asking for.
$trucks=array();
$res = $query->result_array(); // assuming this is actually several trucks
foreach ($res as $r){
// set up the array from the data without writing out every column manually
$truck=array(
'truck'=>$r['truck'],
'truck_data'=>$r,
);
// remove the bit you wanted separately as 'truck' from 'truck_data'
unset($truck['truck_data']['truck']);
// push into $trucks
$trucks[]=$truck;
}

Is this what you need? conversion result is stored in $result
$result = array();
foreach($query->result_array() as $truck)
{
$new_truck = array();
$new_truck['truck'] = $truck['truck'];
$new_truck['truck_data'] = array();
$new_truck['truck_data']['oil_type'] = $truck['oil_type'];
$new_truck['truck_data']['km_min'] = $truck['km_min'];
$new_truck['truck_data']['km_max'] = $truck['km_max'];
array_push($result, $new_truck);
}

Related

Running mysql query in loop for each entry in array

I am no programmer and could really use some help in configuring a query below such that it will run for each element in an array and finally add the queried data to the 'mArray'.
Below is two examples of the queries I am running. I have many more of these so it would be much more practical to include all of the ID's in an array and run a foreach loop based on the number of array elements.
$sth = mysqli_query($conn, "SELECT * FROM {$tableName} WHERE ID = 'List1'");
$list1Array = array();
while($r = mysqli_fetch_array($sth)) {
For ($n = 1; $n <= $CI_NOYEARS; $n++){
$list1Array['data'][] = $r[$n];
}
}
$sth = mysqli_query($conn, "SELECT * FROM {$tableName} WHERE ID = 'List2'");
$list2Array = array();
while($r = mysqli_fetch_assoc($sth)) {
For ($n = 1; $n <= $CI_NOYEARS; $n++){
$list2Array['data'][] = $r[$n];
}
}
$mArray = array();
$mArray['list1'] = $list1Array;
$mArray['list2'] = $list2Array;
I have been trying to create this using a simple array and foreach statement as below. However, I just can't seem to make this work. Any help is much appreciated.
$idArray = array(
"List1",
"List2",
);
foreach($idArray as $val) {
$sth = mysqli_query($conn, "SELECT * FROM {$tableName} WHERE ID = $val");
$yearsArray = array(); // Not sure what to do here
while($r = mysqli_fetch_array($sth)) {
For ($n = 1; $n <= $CI_NOYEARS; $n++){
$yearsArray['data'][] = $r[$n]; // Again not sure what to do here
}
}
}

Setting up array key/value pairs and accessing

I have set up an array called $compData by importing data from MySql and pushing two separate arrays called $yearsArray and $salesArray into $compData. Before pushing these two arrays to $compData I have first set their ['name'] to 'Year' and 'Sales', respectively. The code for this is included below.
$sth = mysqli_query($conn, "SELECT * FROM {$tableName} WHERE ID = 'ID_YEAR'");
$yearsArray = array();
$yearsArray['name'] = 'Year';
while($r = mysqli_fetch_array($sth)) {
For ($n = 1; $n <= $CI_YEARS; $n++){
$yearsArray['data'][] = $r["Year$n"];
}
}
$sth = mysqli_query($conn, "SELECT * FROM {$tableName} WHERE ID = 'IS_SALES'");
$salesArray = array();
$salesArray['name'] = 'Sales';
while($rr = mysqli_fetch_assoc($sth)) {
For ($n = 1; $n <= $CI_YEARS; $n++){
$salesArray['data'][] = $rr["Year$n"];
}
}
$compData = array();
array_push($compData,$yearsArray); // 0
array_push($compData,$salesArray); // 1
Now I want to access and echo the data in $compData by using the code below, but this doesn't work. I am not very comfortable with PHP and am wondering if I am not using the ['Year'] and ['Sales'] identifiers correctly. Any help is much appreciated.
foreach($compData['Year'] as $result) {
echo $result, '<br>';
}
foreach($compData['Sales'] as $result) {
echo $result, '<br>';
}
You've set 'Year' as the value of key 'name', but try to use it as key (of another array).
Now you have
echo $compData[0]['name']; // -> 'Year'
echo $compData[1]['name']; // -> 'Sales'
You probably want
$compData = array();
$compData['Year'] = $yearsArray;
$compData['Sales'] = $salesArray;
instead of the array_push..

How to sort associative array by column that contains previous id value?

I have such associative array. The key prev contains a value to match the id value of the previous item.
When prev is 0 then it's the first item.
Correct order should be by index prev:
$data[3]
$data[1]
$data[0]
$data[4]
$data[2]
but I don't know how to achieve this.
$data[0]['id'] = 10;
$data[0]['name'] = 'Zoe';
$data[0]['prev'] = 20;
$data[1]['id'] = 20;
$data[1]['name'] = 'Tom';
$data[1]['prev'] = 40;
$data[2]['id'] = 30;
$data[2]['name'] = 'Andy';
$data[2]['prev'] = 50;
$data[3]['id'] = 40;
$data[3]['name'] = 'Kathy';
$data[3]['prev'] = 0;
$data[4]['id'] = 50;
$data[4]['name'] = 'Barbara';
$data[4]['prev'] = 10;
I think this is what you want to do:
<?php
$data = array();
$data[0]['id'] = 10;
$data[0]['name'] = 'Zoe';
$data[0]['prev'] = 20;
$data[1]['id'] = 20;
$data[1]['name'] = 'Tom';
$data[1]['prev'] = 40;
$data[2]['id'] = 30;
$data[2]['name'] = 'Andy';
$data[2]['prev'] = 50;
$data[3]['id'] = 40;
$data[3]['name'] = 'Kathy';
$data[3]['prev'] = 0;
$data[4]['id'] = 50;
$data[4]['name'] = 'Barbara';
$data[4]['prev'] = 10;
$nextId = 0;
$results = array();
while (count($data) > 0) {
$matchFound = false;
foreach ($data as $key=>$val) {
if ($val['prev'] === $nextId) {
$results[] = $val;
$nextId = $val['id'];
unset($data[$key]);
$matchFound = true;
break;
}
}
if (!$matchFound) break;
}
The outer while loops checks if the $data array still has elements. The inner for loop searches for the array with element 'prev' equal to the $nextId that we are looking for (initially set to 0). When it finds it, it assigns the id to $next, removes the element from the original array, and adds the element to our sorted array.
Do you mean order by "pre"? You want PHP's usort() function:
<?php
$data = array();
$data[0]['id'] = 10;
$data[0]['name'] = 'Zoe';
$data[0]['prev'] = 20;
$data[1]['id'] = 20;
$data[1]['name'] = 'Tom';
$data[1]['prev'] = 40;
$data[2]['id'] = 30;
$data[2]['name'] = 'Andy';
$data[2]['prev'] = 50;
$data[3]['id'] = 40;
$data[3]['name'] = 'Kathy';
$data[3]['prev'] = 0;
$data[4]['id'] = 50;
$data[4]['name'] = 'Barbara';
$data[4]['prev'] = 10;
function my_order($a,$b) {
return $a['prev'] > $b['prev'];
}
usort($data, "my_order");
print_r($data); //Kathy, Barbara, Zoe, Tom, Andy
Using the function "my_order", which compares $data[$x]['prev'] to $data[$x+1]['prev'], you can yield the results sorted by the "prev" values of the array.
You can use PHP's usort function to do so. It takes an array as the first parameter and then a comparison function as the second. From the documentation:
function cmp($a, $b){
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}
$a = array(3, 2, 5, 6, 1);
usort($a, "cmp");
The comparison function returns 0 if they're equivalent, -1 if a comes before b, and 1 if b comes before a. You can order it however you like.
For you, it could look like:
function cmp($a, $b){
if ($a['prev'] == $b['prev']) {
return 0;
}
return ($a['prev'] < $b['prev']) ? -1 : 1;
}
usort($data, "cmp");
you should try this hope it helps you
$data = array();
$data[0]['id'] = 10;
$data[0]['name'] = 'Zoe';
$data[0]['prev'] = 20;
$data[1]['id'] = 20;
$data[1]['name'] = 'Tom';
$data[1]['prev'] = 40;
$data[2]['id'] = 30;
$data[2]['name'] = 'Andy';
$data[2]['prev'] = 50;
$data[3]['id'] = 40;
$data[3]['name'] = 'Kathy';
$data[3]['prev'] = 0;
$data[4]['id'] = 50;
$data[4]['name'] = 'Barbara';
$data[4]['prev'] = 10;
function sortIt($data) {
$output = array();
$key = array_search(0, array_column($data, 'prev'));
$output[] = $data[$key];
unset($data[$key]);
$data = array_combine(
array_column($data,'prev'),
$data
);
while($data){
$last = end($output);
$output[] = $data[$last['id']];
unset($data[$last['id']]);
}
return $output;
}
echo '<pre>';
print_r(sortIt($data));
You could get a bit better response time using a hash:
foreach($data as $rec) {
$hash[$rec["prev"]] = $rec;
}
$id = "0";
while (isset($hash[$id])) {
$result[] = $curr = $hash[$id];
$id = $curr["id"];
}
See it run on eval.in

For Loop print results line by line

Hi i have following php codes(part of my full code):
$instance = $old_instance;
$instance['title'] = strip_tags($new_instance['title']);
$instance['serisname1'] = $new_instance['serisname1'];
$instance['serisname2'] = $new_instance['serisname2'];
$instance['serisname3'] = $new_instance['serisname3'];
$instance['serisname4'] = $new_instance['serisname4'];
$instance['serisname5'] = $new_instance['serisname5'];
$instance['serisname6'] = $new_instance['serisname6'];
$instance['serisname7'] = $new_instance['serisname7'];
$instance['serisname8'] = $new_instance['serisname8'];
$instance['serisname9'] = $new_instance['serisname9'];
$instance['serisname10'] = $new_instance['serisname10'];
$instance['serisname11'] = $new_instance['serisname11'];
$instance['serisname12'] = $new_instance['serisname12'];
$instance['serisname13'] = $new_instance['serisname13'];
$instance['serisname14'] = $new_instance['serisname14'];
$instance['serisname15'] = $new_instance['serisname15'];
return $instance;
for($x = 1; $x <= 15; $x++)
$serisname = $instance[serisname.$x];
$items[] = $serisname;
print_r($items);
my export :
array ( [0] => The Flash )
i want its be like :
array ( [0] => The Flash [1] => Arrow [2] => Game Of Throne and etc...)
the problem is its only echo last result but i want its echo every 15 results line by line.
for($x = 1; $x <= 15; $x++){
$serisname = $instance['serisname'.$x];
$items[] = $serisname;
}
print_r($items);
If I understead your question correctly, you can try this:
$count = 0;
for($x = 0; $x <= count($instance); $x++) {
$items[$x][] = $instance[serisname.$x];
if($count == 15) {
$count = 0;
}
}
Maybe can include the instance before the loop in your question so we can replicate the array?

SQL results to PHP array

I've got the following sql query:
$sql = "SELECT lat, lang
FROM users";
I then use the following code to put the results of the array into two arrays, one for lat and one for lang.
$i = 0;
foreach($results as $row) {
$latArray = array();
$langArray = array();
$latArray[$i] = $row['lat'];
$langArray[$i] = $row['lang'];
$i = ($i + 1);
}
However, it seems that only the last value that is passed to the array is stored. When I echo out each value of the array I get the following error: Undefined offset: 0 which I believe means theres nothing at latArray[0].
I'm sure I've missed something obvious here but why aren't all the values copied to the new array?
$i = 0;
$latArray = array(); //Declare once, do not redeclare in the loop
$langArray = array();
foreach($results as $row) {
$latArray[$i] = $row['lat'];
$langArray[$i] = $row['lang'];
$i = ($i + 1);
}
Declare your array before the loop
$latArray = array();
$langArray = array();
foreach($results as $row) {
$latArray[$i] = $row['lat'];
$langArray[$i] = $row['lang'];
$i = ($i + 1);
}
You should put
$latArray = array();
$langArray = array();
Before foreach cycle (like you do with your counter $i), 'cause with every new value from $result it resets thous values..
so your code will look like:
$i = 0;
$latArray = array();
$langArray = array();
foreach($results as $row) {
$latArray[$i] = $row['lat'];
$langArray[$i] = $row['lang'];
$i = ($i + 1);
}
use fetch_assoc instead:
$latArray = array();
$langArray = array();
while($row = mysql_fetch_assoc($your_query)){
$latArray[$i] = $row['lat'];
$langArray[$i] = $row['lang'];
$i++;
}
if u are using msqli us mysqli_fetch_assoc

Categories