multidimensional search not showing all results - php

I have a multidimensional array search
my array looks like this
Array
(
[0] => Array
(
[id] => 1
[location] => 3
[location_fees] => 3
[gross_percentage] => 25
[transaction_percentage] => 0
[user_name] => admin
[user_id] => 1
[gross] => yes
[transaction] => no
)
[1] => Array
(
[id] => 2
[location] => 5
[location_fees] => 5
[gross_percentage] => 0
[transaction_percentage] => 24
[user_name] => admin
[user_id] => 1
[gross] => no
[transaction] => yes
)
[2] => Array
(
[id] => 3
[location] => 2
[location_fees] => 5
[gross_percentage] => 10
[transaction_percentage] => 0
[user_name] => admin
[user_id] => 1
[gross] => yes
[transaction] => no
)
)
i use the following php, i know it can probably be done cleaner or a lot less code so if you have any ideas how to get the same result i am def all about learning and i am all ears!
so here is the PHP i use:
$key = false;
$search = ['gross' => 'yes'];
foreach ($results as $k => $v) {
if ($v['gross'] == $search['gross'] ) {
$key = $k;
$location_fees = array_search('yes', array_column($results, 'gross','location_fees'));
echo "The location fees: ". $location_fees ." % <br><br>";
$gross_percentage = array_search('yes', array_column($results, 'gross', 'gross_percentage'));
echo "The gross_percentage is: ".$gross_percentage ."% <br><br>";
} else {
$tran_perc = array_search('yes', array_column($results, 'transaction', 'transaction_percentage'));
echo "The locations percentage is: ".$tran_perc ." % <br>";
$the_loc = array_search('yes', array_column($results, 'transaction', 'location'));
echo "The location is: ".$the_loc ." <br>";
$location_fees = array_search('no', array_column($results, 'gross','location_fees'));
echo "The location fees: ". $location_fees ." % <br><br>";
}
}
and my results on the page look like this:
key 0
The location fees: 3 %
The gross_percentage is: 25%
key 1
The locations percentage is: 24 %
The location is: 5
The location fees: %
key 2
The location fees: 8 %
The gross_percentage is: 25%
it refuses to show the locations fee from key #1
NOW the strange parts is, if i change the location fees to say 3, it then shows up. but it will not with the number "5" which is also the location #
Is there a reason this is a conflict with JUST that number "5"? Notice Key "0" has location of "3" and location fees of "3" and it does not cause any issues.
I have been stuck on this for hours, it will work for keys # 0 and #2 without any issues. Any ideas?

The reason you are running into this issue is your call to array_column:
array_column($results, 'gross','location_fees')
this causes the gross values from $results to be re-indexed by the location_fees values, which for your data would result in something like
[3 => 'yes', 5 => 'no', 5 => 'yes']
As you can see, you have two 5 numeric keys, which is not valid, so the second one overwrites the first and you end up with
[3 => 'yes', 5 => 'yes']
and your array_search for no fails, hence you get no results. You will have this problem everywhere you get a replicated value.
I'm not sure why you are taking this approach anyway. It seems you have the numbers you want in $v anyway:
$search = ['gross' => 'yes'];
foreach ($results as $k => $v) {
echo "key $k<br>" . PHP_EOL;
if ($v['gross'] == $search['gross'] ) {
$location_fees = $v['location_fees'];
echo "The location fees: ". $location_fees ." % <br><br>" . PHP_EOL;
$gross_percentage = $v['gross_percentage'];
echo "The gross_percentage is: ".$gross_percentage ."% <br><br>" . PHP_EOL;
} else {
$tran_perc = $v['transaction_percentage'];
echo "The locations percentage is: ".$tran_perc ." % <br>" . PHP_EOL;
$the_loc = $v['location'];
echo "The location is: ".$the_loc ." <br>" . PHP_EOL;
$location_fees = $v['location_fees'];
echo "The location fees: ". $location_fees ." % <br><br>" . PHP_EOL;
}
}
Output:
key 0<br>
The location fees: 3 % <br><br>
The gross_percentage is: 25% <br><br>
key 1<br>
The locations percentage is: 24 % <br>
The location is: 5 <br>
The location fees: 5 % <br><br>
key 2<br>
The location fees: 5 % <br><br>
The gross_percentage is: 10% <br><br>
Demo on 3v4l.org

Related

Sort an array with the output by value [duplicate]

This question already has answers here:
How can I sort arrays and data in PHP?
(14 answers)
Closed 5 years ago.
I need to sort the multidimensional array with output by value. I can not group the nested arrays by date and output it with the title (date).
There is an array:
Array (
[0] => (
[ID] => 959
[title] => title
[post_date] => 2018-01-01 10:17:49
)
[1] => (
[ID] => 960
[title] => title
[post_date] => 2018-01-01 10:17:49
)
[2] => (
[ID] => 961
[title] => title
[post_date] => 2018-01-02 10:17:49
)
[3] => (
[ID] => 962
[title] => title
[post_date] => 2014-01-02 10:17:49
)
[4] => (
[ID] => 963
[title] => title
[post_date] => 2014-01-03 10:17:49
)
)
As a result, I need to get this.
There is a date as the header and all arrays in which this date.
Result
- 2018-01-01 -
id: 959 Title
id: 560 Title
- 2018-01-02 -
id: 961 Title
id: 562 Title
- 2018-01-02 -
id: 963 Title
.....
have you done with part about sorting? I assume you are. So the only thing left is "grouping".
But actually you don't need to group data. Just iterate sorted items one by one and remember date from previous element. Once dates for current element and for previous one differ - you output "header". Something like that:
$data = [[a=> 2, b=> 1], [a=> 2, b=> 4], [a=> 3, b=> 1], [a=> 4, b=> 0]];
$previous_a = null;
foreach($data as $item) {
if ($item['a'] != $previous_a) {
echo 'header --- '.$item['a'].'<br />';
}
$previous_a = $item['a'];
echo $item['b'].'<br />';
}
You could try something like this :
$aggreg = [] ;
foreach ($array as $item) {
$day = $item['post_date'];
// if you want to group by day, just use $day = substr($day,0,10) ;
$aggreg[$day][] = 'id: ' . $item['ID'] . " " . $item['title'] ;
}
krsort($aggreg) ; // or ksort() or just comment this line.
// then build the output :
$output = "" ;
foreach ($aggreg as $day => $data) {
$output .= "- " .substr($day,0,10) . " -\n\n" . implode("\n", $data) . "\n\n" ;
}
print $output ;
Will outputs :
- 2018-01-02 -
id: 961 title
- 2018-01-01 -
id: 959 title
id: 960 title
- 2014-01-03 -
id: 963 title
- 2014-01-02 -
id: 962 title
NB If you have to output this in HTML, please change \n to <br>

PHP Loop with While Loop confusion

I currently have a simple WHILE loop running as follows:
while($los = $result->fetch_row())
{
echo"<tr><td>".$los[0]."</td>";
echo"<td>".$los[1]."</td>";
echo"<td>".$los[2]."</td></tr>";
}
The contents of $los is as follows:
London => 15 => 32
Glasgow => 23 => 45
Leeds => 1 => 12
Truro => 5 => 23
All working fine but what I am struggling with is that I have a second array $outs, the contents of which are:
London => 3
Glasgow => 5
Liverpool => 2
Poole => 1
Within the first while loop I am trying to subtract the value for $outs from $los when the location name matches. I have tried adding the following inside the while loop but no joy:
if($los[0] == $outs[0]){
$los[1] = $los[1]-$outs[1];
}
But no joy, also when I have tried print_r($outs) from within the while loop, all it returns is:
Poole => 1
Poole => 1
Poole => 1
Poole => 1
I cannot fathom where I am going wrong or even if this is possible. Is the $outs array being modified as it's within the first loop? Any ideas, suggestion or pointers welcomed on how I might achieve this.
VAR DUMPS
So, as requested the contents of the two arrays are:
$los
London => 15 => 32
Glasgow => 23 => 45
Leeds => 1 => 12
Truro => 5 => 23
$outs
London => 3
Glasgow => 5
Liverpool => 2
Poole => 1
However, when I vardump or print_r for $outs when it is in the while($los = $result->fetch_row()) the contents are:
Poole => 1
Poole => 1
Poole => 1
Poole => 1
FURTHER CODE
The code to obtain the array for $outs is:
$query19 = "SELECT Country, COUNT(Country), Resp FROM `tresults_` WHERE q39 = 'Complete' GROUP BY Country;";
$result19 = $mysqli->query($query19);
while($row19 = $result19->fetch_assoc()){
$outs = $row19;
}
Please consider to post the RAW Content that was produced by var_dump and include a full but minimal script to produce the error.
What is unclear here seem to be if $outs is a (1) Key-Value Array or a if it's (2) containing sub-arrays.
Option 1:
$outs = [
"London" => 3,
"Glasgow" => 5,
"Liverpool" => 2,
"Poole" => 1
];
Option 2:
$outs = [
["London", 3],
["Glasgow", 5],
["Liverpool", 2],
["Poole", 1]
];
I did for testing assume your input rows look like this:
$citys = [
["London", 15, 32],
["Glasgow", 23, 45],
["Leeds", 1, 12],
["Truro", 5, 23]
];
Depending on this you sould adjust the if inside your while loop.
For option 1:
foreach ($citys as $los) {
if (array_key_exists($los[0], $outs)) {
$los[1] = $los[1] - $outs[$los[0]];
}
echo " <tr><td > " . $los[0] . "</td > ";
echo "<td > " . $los[1] . "</td > ";
echo "<td > " . $los[2] . "</td ></tr > ";
}
For option 2 it's a little bit more code, as we need to search for the cityname index inside $outs first. In php > 5.5 it could be done using array_column which would be easier.
foreach ($citys as $los) {
$indexInOuts = null;
foreach($outs as $index => $out){
if($los[0] === $out[0]){
$indexInOuts = $index;
break;
}
}
if($indexInOuts !== null){
$los[1] = $los[1] - $outs[$indexInOuts][1];
}
echo " <tr><td > " . $los[0] . "</td > ";
echo "<td > " . $los[1] . "</td > ";
echo "<td > " . $los[2] . "</td ></tr > ";
}
The output for both options would be like:
London 12 32
Glasgow 18 45
Leeds 1 12
Truro 5 23
And as stated in the comments you are replacing the $outs every time. So edit it to look like this:
$outs = [];
while ($row19 = $result19->fetch_assoc()) {
$outs[] = $row19;
}

How to use array_push with associative array and index key?

I am a bit 'rusty with php as it happens that sometimes I use it for weeks and sometimes it happens that you do not use for months. Either way I'm trying to pass values of another array are "array", on another array in an orderly manner ... What I want to do is essentially create a key that allows me to organize incremental values per line, in particular;
array content
Array
(
[key] => value
[2] => 1
[3] => Inter
[4] => 4
[5] => 4
[6] => 0
[7] => 0
[8] => 5
[9] => 1
[10] => +4
[11] => 12
[12] => Chievo Verona - Inter 0 - 1
[13] => Inter - Milan 1 - 0
[14] => Carpi - Inter 1 - 2
[15] => Inter - Atalanta 1 - 0
[16] => ;
[17] => 2
[18] => Torino
[19] => 4
[20] => 3
[21] => 1
[22] => 0
[23] => 9
[24] => 4
[25] => +5
[26] => 10
[27] => Torino - Sampdoria 2 - 0
[28] => Hellas Verona - Torino 2 - 2
[29] => Torino - Fiorentina 3 - 1
[30] => Frosinone - Torino 1 - 2
[31] => ;
[32] => 3
[33] => Fiorentina
[34] => 4
[35] => 3
[36] => 0
[37] => 1
[38] => 5
[39] => 3
[40] => +2
[41] => 9
[42] => Carpi - Fiorentina 0 - 1
[43] => Fiorentina - Genoa 1 - 0
[44] => Torino - Fiorentina 3 - 1
[45] => Fiorentina - Milan 2 - 0
[46] => ;
[47] => 4
[48] => Roma
[49] => 4
[50] => 2
the ";" It'll need to be able to recognize where you break the line, I do not remember if there is any method that allows me to access the next key.
Currently my code is:
$classifica = array("key" => "value");
function buildArrayClassifica()
{
global $array;
global $classifica;
$i = 0;
foreach(array_slice($array,1) as $key => $value)
{
if($value != ";")
{
array_push($classifica[$i], $value); //there is a problem
echo $value . " ";
}
else if($value == "value ")
{
continue;
}
else
{
$i++;
echo "<br/>";
}
}
}
The code I will return this error:
Warning: array_push () Expects parameter 1 to be array, null given in...
in particular on array_push, it seems not to accept incremental keys or maybe I'm doing it the wrong way.
Can anyone tell me how to solve?
UPDATING
As you have seen the issue is not simple and it is quite difficult to explain the problem, but I will try to be even clearer to meet.
As you can see above you are the structure of the array "array", but is a disordered structure that needs to be ordered in an additional array. To recapitulate the structure of the array "array" is:
1 , Inter , 4 , 4 , 0 , 0 , 5 , 1 , +4 , 12 , Chievo Verona - Inter 0 - 1 , Inter - Milan 1 - 0 , Carpi - Inter 1 - 2 , Inter - Atalanta 1 - 0 , ;
the ";" means that the line is finished. So the next value near the ";" means that a new line coming. What I need is move all the value of "array" in array classifica, but I want organize them for:
ROW1 => 1 , Inter , 4 , 4 , 0 , 0 , 5 , 1 , +4 , 12 , Chievo Verona - Inter 0 - 1 , Inter - Milan 1 - 0 , Carpi - Inter 1 - 2 , Inter - Atalanta 1 - 0
ROW2 => Other values...
So the ROW1, 2 .. rapresents the key of the array classifica. I'm trying to push the value inside a row and after it increment $i index but the code doesn't add the value because the index replace in loop the actual key, for example:
actual foreach content:
$i = 0
value = "Inter"
content of array=> [0] => Inter
now the $i is ever 0 because the row isn't finished yet, the ";"
it has not yet been reached, so the next content of foreach is:
"1" but replace the "Inter" value, so this is a problem.
You cannot use array_push() in this way. Please try:
$classifica = array();
function buildArrayClassifica()
{
global $array;
global $classifica;
$i = 0;
foreach(array_slice($array,1) as $key => $value)
{
if($value != ";")
{
$classifica[$i] = $value;
echo $value . " ";
}
else if($value == "value ")
{
continue;
}
else
{
$i++;
echo "<br/>";
}
}
}
This will create indexes (the value of $i) when $value is added to your array. array_push() would place the $value at the next numerical index and may not be what you want by the looks of it. You could also use $key if you wanted the index to match.
EDIT
After more discussion, you have a specific format, where the first Item is the Key, the following indexes are values, and when you encounter the value ";", it starts the sequence over. So when we read:
[2] => 1
[3] => Inter
[4] => 4
[5] => 4
[6] => 0
[7] => 0
[8] => 5
[9] => 1
[10] => +4
[11] => 12
[12] => Chievo Verona - Inter 0 - 1
[13] => Inter - Milan 1 - 0
[14] => Carpi - Inter 1 - 2
[15] => Inter - Atalanta 1 - 0
[16] => ;
The first value, '1' is our Index, the following values become the Value for this Index, and we stop reading when we find ";". That would look something like:
<?php
function buildArrayClassifica($dataArray){
$resultArray = array();
$t = array_values($dataArray);
print_r($t);
$lsc = 0;
foreach($t as $k => $v){
if((string)$v == ';'){
echo "<p>Found ';' at [$k] => {$v}</p>";
// Found end of data
// Save position
$scp = $k;
echo "<p>Recorded [$scp] position for ';'.</p>";
// Reset to find the Index, first int in this series
$c=$lsc; // First pass this should be 0
// Set the index
if($lsc ==0){
// First pass
$index = intval($t[$c]);
echo "<p>Getting Index from position [" . ($c) ."] => $index for Result Array.</p>";
$c++;
} else {
$c++;
$index = intval($t[$c]);
echo "<p>Getting Index from position [" . ($c) ."] => $index for Result Array.</p>";
$c++;
}
echo "<p>Starting to read data from [$c] until [$scp].</p>";
// Init implode variable
$data = "";
for($c;$c<$scp;$c++){
//Populate variable with the series up to semicolon, skipping first element (index)
$data .= $t[$c] . ", ";
}
echo "<p>Data collected for this round: '" . htmlentities(substr($data,0,-2)) . "'</p>";
// populate result array
$resultArray[$index] = substr($data,0,-2);
echo "<p>resultArray[$index] => " . htmlentities($resultArray[$index]) . "</p><br />";
$lsc = $scp;
}
}
return $resultArray;
}
$oldArray = array(1, "Inter", 4 , 4 , 0 , 0 , 5 , 1 , "+4" , 12 , "Chievo Verona - Inter 0 - 1", "Inter - Milan 1 - 0", "Carpi - Inter 1 - 2", "Inter - Atalanta 1 - 0", ";", 2, "Torino", 4, 3, 1, 0, 9, 4, '+5', 10, "Torino - Sampdoria 2 - 0", "Hellas Verona - Torino 2 - 2", "Torino - Fiorentina 3 - 1", "Frosinone - Torino 1 - 2", ";", 3, "apple", 0, 4, 6, "apple", ";");
$classifica = buildArrayClassifica($oldArray);
print_r($classifica);
?>
My initial testing seems to work for what you described. The first element of the array becomes the Index, the next few values become imploded until we reach the semicolon (;) value.
What I see as a result:
Array ( [1] => Inter, 4, 4, 0, 0, 5, 1, +4, 12, Chievo Verona - Inter 0 - 1, Inter - Milan 1 - 0, Carpi - Inter 1 - 2, Inter - Atalanta 1 - 0 [2] => Torino, 4, 3, 1, 0, 9, 4, +5, 10, Torino - Sampdoria 2 - 0, Hellas Verona - Torino 2 - 2, Torino - Fiorentina 3 - 1, Frosinone - Torino 1 - 2 [3] => apple, 0, 4, 6, apple )
ASIDE
If it were me, I would push it all into an array like so:
$data = array();
for($c;$c<$scp;$c++){
$data[] = $t[$c];
}
$resultArray[$index] = $data;
Or if you really want a string:
$resultArray[$index] = implode(", ", $data);
Hope that helps.

Add value in specific index array

i have array data like this.
[0] => Array (
[id] => 1
[id_requestor] => 1
[jam_input] => 2015-06-20 06:00:00
[jam_pakai] => 2015-06-28 08:00:00
[total_poin] => 30
)
[1] => Array (
[id] => 2
[id_requestor] => 2
[jam_input] => 2015-06-20 07:00:00
[jam_pakai] => 2015-06-28 08:00:00
[total_poin] => 10
)
[2] => Array (
[id] => 3
[id_requestor] => 3
[jam_input] => 2015-06-20 06:30:00
[jam_pakai] => 2015-06-28 08:00:00
[total_poin] => 5
)
In above data, there is total_poin. This total_poin that i use later.
I want to sort total_poin array descending.
But i wont to use php built in array function.
Cause i have to use method from research paper like this.
for i=0 to i<main queue.size
if jobi+1 length > jobi length then
add jobi+1 in front of job i in the queue
end if
if main queue.size = 0 then
add job i last in the main queue
end if
And here is my implementation :
function LJFAlgorithm($time_str) {
$batchData = getBatch($time_str);
$ljf = [];
for ($i=0; $i < count($batchData)-1; $i++) {
echo $batchData[$i+1]['total_poin'] ." >= ". $batchData[$i]['total_poin'] . " = " . ($batchData[$i+1]['total_poin'] >= $batchData[$i]['total_poin']);
if ($batchData[$i+1]['total_poin'] >= $batchData[$i]['total_poin']) {
echo ", Add " . $batchData[$i+1]['total_poin'] . " in front of " . $batchData[$i]['total_poin'];
} else {
echo ", Add " . $batchData[$i]['total_poin'] . " in front of " . $batchData[$i+1]['total_poin'];
}
echo '<br/>';
}
print_r($ljf);
}
But it not work perfectly, i get one data missing.
Here is my output code :
10 >= 30 = , Add 30 in front of 10
5 >= 10 = , Add 10 in front of 5
5 value not added in array.
How to fix that?
Thank you very much.
Try this
for ($i=0; $i <= count($batchData)-1; $i++)

PHP filter and sum array values

I've got a php script with following array (date,task,actor,hh:mm).
Array
(
[0] => 2013-01-29|Making movies|Laurel|07:30
[1] => 2013-01-29|Making movies|Hardy|00:30
[2] => 2013-01-29|Learning PHP|Hardy|07:00
[3] => 2013-01-29|Singing autographs|Keaton|07:30
[4] => 2013-01-29|Making movies|Lloyd|07:30
[5] => 2013-01-28|Learning PHP|Laurel|07:30
[6] => 2013-01-28|Making movies|Hardy|07:30
[7] => 2013-01-28|Learning PHP|Keaton|07:30
[8] => 2013-01-28|Making movies|Lloyd|07:30
[9] => 2013-01-27|Learning PHP|Laurel|05:30
[10] => 2013-01-27|Making movies|Laurel|02:30
[11] => 2013-01-27|Learning PHP|Hardy|07:30
[12] => 2013-01-27|Making movies|Keaton|07:30
[13] => 2013-01-27|Making movies|Lloyd|07:30
)
I'd like to create a filter that lists the tasks and sums the time values of each task, for example:
Learning PHP (<-selected option)
2013-01-29 Hardy 07:00
2013-01-28 Laurel 07:30
2013-01-28 Keaton 07:30
2013-01-27 Laurel 05:30
2013-01-27 Hardy 07:30
=======================
TOTAL 35:00
What would be the way to make this happen?
Any suggestions or next steps are more than welcome.
This would be easier to filter if you had a multidimensional array. Something like this would work for the current structure though:
$task = "Learning PHP";
foreach($arr as $k=>$v) {
$pieces = explode("|", $v);
if($pieces[1]==$task) {
$total += (int) str_replace(':','',$pieces[3]);
echo $pieces[0] . " " . $pieces[2] . " " . $pieces[3];
}
}
echo "Total: " . $total;

Categories