Ordering multidimensional associative arrays - php

I want to order this array by price AND keep my keys without them being changed.
Here is what I have been working with.
<?php
$a = array(
1=>array('price'=>9.25,'timestamp_added'=>1301945848,'name'=>'pencils'),
4=>array('price'=>19.15,'timestamp_added'=>1299267448,'name'=>'crayon box'),
15=>array('price'=>4.25,'timestamp_added'=>1299785848,'name'=>'markers'),
2=> array('price'=>4.28,'timestamp_added'=>1299785848,'name'=>'eraser'),
44=>array('price'=>13.99,'timestamp_added'=>1299872248,'name'=>'trapper'),
32=>array('price'=>9.25,'timestamp_added'=>1299872248,'name'=>'notebook'),
14=>array('price'=>13.99,'timestamp_added'=>1301945848,'name'=>'sharpener'),
5=>array('price'=>15.01,'timestamp_added'=>1299872248,'name'=>'calculator')
);
function printList( $a ){
echo "<br />";
foreach ($a as $key => $value){
echo "<br /> Product ID $key Price: " . $value['price'] . " Timestamp: " . $value['timestamp_added'] . " Name: " . $value['name'];
}
}
printList( $a );
$price = array();
foreach ($a as $key => $row)
{
$price[$key] = $row['price'];
}
array_multisort($price, SORT_ASC, $a);
printList( $a );
?>
Output:
Product ID 1 Price: 9.25 Timestamp: 1301945848 Name: pencils
Product ID 4 Price: 19.15 Timestamp: 1299267448 Name: crayon box
Product ID 15 Price: 4.25 Timestamp: 1299785848 Name: markers
Product ID 2 Price: 4.28 Timestamp: 1299785848 Name: eraser
Product ID 44 Price: 13.99 Timestamp: 1299872248 Name: trapper
Product ID 32 Price: 9.25 Timestamp: 1299872248 Name: notebook
Product ID 14 Price: 13.99 Timestamp: 1301945848 Name: sharpener
Product ID 5 Price: 15.01 Timestamp: 1299872248 Name: calculator
Product ID 0 Price: 4.25 Timestamp: 1299785848 Name: markers
Product ID 1 Price: 4.28 Timestamp: 1299785848 Name: eraser
Product ID 2 Price: 9.25 Timestamp: 1299872248 Name: notebook
Product ID 3 Price: 9.25 Timestamp: 1301945848 Name: pencils
Product ID 4 Price: 13.99 Timestamp: 1299872248 Name: trapper
Product ID 5 Price: 13.99 Timestamp: 1301945848 Name: sharpener
Product ID 6 Price: 15.01 Timestamp: 1299872248 Name: calculator
Product ID 7 Price: 19.15 Timestamp: 1299267448 Name: crayon box
It sorts the array, but the keys are changed. How can I keep the keys labeled the way they were?

You can use uasort function
$a = array(
1=>array('price'=>9.25,'timestamp_added'=>1301945848,'name'=>'pencils'),
4=>array('price'=>19.15,'timestamp_added'=>1299267448,'name'=>'crayon box'),
15=>array('price'=>4.25,'timestamp_added'=>1299785848,'name'=>'markers'),
2=> array('price'=>4.28,'timestamp_added'=>1299785848,'name'=>'eraser'),
44=>array('price'=>13.99,'timestamp_added'=>1299872248,'name'=>'trapper'),
32=>array('price'=>9.25,'timestamp_added'=>1299872248,'name'=>'notebook'),
14=>array('price'=>13.99,'timestamp_added'=>1301945848,'name'=>'sharpener'),
5=>array('price'=>15.01,'timestamp_added'=>1299872248,'name'=>'calculator')
);
function printList( $a ){
echo "<br />";
foreach ($a as $key => $value){
echo "<br /> Product ID $key Price: " . $value['price'] . " Timestamp: " . $value['timestamp_added'] . " Name: " . $value['name'];
}
}
printList( $a );
function sbyprice($a, $b)
{
return ($a['price'] >= $b['price']) ? 1 : 0;
}
uasort($a , "sbyprice");
printList( $a );
?>
Output :
Product ID 1 Price: 9.25 Timestamp: 1301945848 Name: pencils
Product ID 4 Price: 19.15 Timestamp: 1299267448 Name: crayon box
Product ID 15 Price: 4.25 Timestamp: 1299785848 Name: markers
Product ID 2 Price: 4.28 Timestamp: 1299785848 Name: eraser
Product ID 44 Price: 13.99 Timestamp: 1299872248 Name: trapper
Product ID 32 Price: 9.25 Timestamp: 1299872248 Name: notebook
Product ID 14 Price: 13.99 Timestamp: 1301945848 Name: sharpener
Product ID 5 Price: 15.01 Timestamp: 1299872248 Name: calculator
Product ID 15 Price: 4.25 Timestamp: 1299785848 Name: markers
Product ID 2 Price: 4.28 Timestamp: 1299785848 Name: eraser
Product ID 32 Price: 9.25 Timestamp: 1299872248 Name: notebook
Product ID 1 Price: 9.25 Timestamp: 1301945848 Name: pencils
Product ID 44 Price: 13.99 Timestamp: 1299872248 Name: trapper
Product ID 14 Price: 13.99 Timestamp: 1301945848 Name: sharpener
Product ID 5 Price: 15.01 Timestamp: 1299872248 Name: calculator
Product ID 4 Price: 19.15 Timestamp: 1299267448 Name: crayon box

uasort is the thing for you
for example:
<?php
function my_sort($a,$b)
{
if ($a==$b) return 0;
return ($a<$b)?-1:1;
}
$arr=array("a"=>4,"b"=>2,"c"=>8,d=>"6");
uasort($arr,"my_sort");
?>

Same as others, but using inline function, which may be better:
uasort ( $array , function($a, $b) {
return $a['price'] >= $b['price'] ? 1 : 0 ;
});

usort will solve your issue.Please reffer this link.

Related

PHP for loop with array and array slice functions

As part of an expense data analyze, I am trying to find out top 3 expense categories for each month.Right now I have 3 months data : Array $month0,$month1,$month3.
Right now I am using below code and its working fine
$month0 = array("Bank"=>$Bank[0], "CreditCard"=>$CreditCard[0], "Loan"=>$Loan[0],"Household"=>$Household[0],"Utilities"=>$Utilities[0]);
$month1 = array("Bank"=>$Bank[1], "CreditCard"=>$CreditCard[1], "Loan"=>$Loan[1],"Household"=>$Household[1],"Utilities"=>$Utilities[1]);
$month2 = array("Bank"=>$Bank[2], "CreditCard"=>$CreditCard[2], "Loan"=>$Loan[2],"Household"=>$Household[2],"Utilities"=>$Utilities[2]);
arsort($month0 );
arsort($month1 );
arsort($month2 );
$top3month0 = array_slice($month0, 0, 3);
$top3month1 = array_slice($month1, 0, 3);
$top3month2 = array_slice($month2, 0, 3);
foreach ($top3month0 as $category => $amount){
$cat_top3month0[] = $category;
$amt_top3month0[] = $amount;
}
foreach ($top3month1 as $category => $amount){
$cat_top3month1[] = $category;
$amt_top3month1[] = $amount;
}
foreach ($top3month2 as $category => $amount){
$cat_top3month2[] = $category;
$amt_top3month2[] = $amount;
}
//For Month0
echo "Top 1 category is ".$cat_top3month0[0]." and amount: ".$amt_top3month0[0];
echo "Top 2 category is ".$cat_top3month0[1]." and amount: ".$amt_top3month0[1];
echo "Top 3 category is ".$cat_top3month0[2]." and amount: ".$amt_top3month0[2];
//For Month1
echo "Top 1 category is ".$cat_top3month1[0]." and amount: ".$amt_top3month1[0];
echo "Top 2 category is ".$cat_top3month1[1]." and amount: ".$amt_top3month1[1];
echo "Top 3 category is ".$cat_top3month1[2]." and amount: ".$amt_top3month1[2];
//For Month3
echo "Top 1 category is ".$cat_top3month2[0]." and amount: ".$amt_top3month2[0];
echo "Top 2 category is ".$cat_top3month2[1]." and amount: ".$amt_top3month2[1];
echo "Top 3 category is ".$cat_top3month2[2]." and amount: ".$amt_top3month2[2];
I am trying to use for loop here to reduce the length of the code. I changed above code like below using for loop
for ($i = 0; $i<3; $i++){
$month[i] = array("Bank"=>$Bank[i], "CreditCard"=>$CreditCard[i], "Loan"=>$Loan[i],"Household"=>$Household[i],"Utilities"=>$Utilities[i]);
arsort($month[i] );
$top3month[i] = array_slice($month[i], 0, 3);
foreach ($top3month[i] as $category => $amount){
$cat_top3month[i][] = $category;
$amt_top3month[i][] = $amount;
}
}
//For Month0
/echo "Top 1 category is ".$cat_top3month0[0]." and amount: ".$amt_top3month0[0];
/echo "Top 2 category is ".$cat_top3month0[1]." and amount: ".$amt_top3month0[1];
/echo "Top 3 category is ".$cat_top3month0[2]." and amount: ".$amt_top3month0[2];
//For Month1
echo "Top 1 category is ".$cat_top3month1[0]." and amount: ".$amt_top3month1[0];
echo "Top 2 category is ".$cat_top3month1[1]." and amount: ".$amt_top3month1[1];
echo "Top 3 category is ".$cat_top3month1[2]." and amount: ".$amt_top3month1[2];
//For Month3
echo "Top 1 category is ".$cat_top3month2[0]." and amount: ".$amt_top3month2[0];
echo "Top 2 category is ".$cat_top3month2[1]." and amount: ".$amt_top3month2[1];
echo "Top 3 category is ".$cat_top3month2[2]." and amount: ".$amt_top3month2[2];
But above code is not working. When looking at the debug log I see below error
PHP Warning: Use of undefined constant i - assumed 'i' (this will throw an Error in a future version of PHP)
against line
$month[i] = array("Bank"=>$Bank[i], "CreditCard"=>$CreditCard[i], "Loan"=>$Loan[i],"Household"=>$Household[i],"Utilities"=>$Utilities[i]);
I am new to PHP and still learning. Can someone please tell me the issue with code ? or suggest a better approach to this ?
Update:
Updated the code to correct i to $i
for ($i = 0; $i<3; $i++){
$month[$i] = array("Bank"=>$Bank[$i], "CreditCard"=>$CreditCard[$i], "Loan"=>$Loan[$i],"Household"=>$Household[$i],"Utilities"=>$Utilities[$i]);
arsort($month[$i] );
$top3month[$i] = array_slice($month[$i], 0, 3);
foreach ($top3month[$i] as $category => $amount){
$cat_top3month[$i][] = $category;
$amt_top3month[$i][] = $amount;
}
}
//For Month0
echo "Top 1 category is ".$cat_top3month0[0]." and amount: ".$amt_top3month0[0];
echo "Top 2 category is ".$cat_top3month0[1]." and amount: ".$amt_top3month0[1];
echo "Top 3 category is ".$cat_top3month0[2]." and amount: ".$amt_top3month0[2];
//For Month1
echo "Top 1 category is ".$cat_top3month1[0]." and amount: ".$amt_top3month1[0];
echo "Top 2 category is ".$cat_top3month1[1]." and amount: ".$amt_top3month1[1];
echo "Top 3 category is ".$cat_top3month1[2]." and amount: ".$amt_top3month1[2];
//For Month3
echo "Top 1 category is ".$cat_top3month2[0]." and amount: ".$amt_top3month2[0];
echo "Top 2 category is ".$cat_top3month2[1]." and amount: ".$amt_top3month2[1];
echo "Top 3 category is ".$cat_top3month2[2]." and amount: ".$amt_top3month2[2];
Now I have below errors:
PHP Notice: Array to string conversion in
against line :
$month[$i] = array("Bank"=>$Bank[$i], "CreditCard"=>$CreditCard[$i], "Loan"=>$Loan[$i],"Household"=>$Household[$i],"Utilities"=>$Utilities[$i]);
and
PHP Fatal error: Uncaught Error: Only variables can be passed by reference in
against arsort($month[$i] );

Output from sorted array with SimpleXML, xsort and xpath in PHP

Having solved a chain of other issues with this XML parsing project (thanks to a lovely SO user), I'm now stuck at the next hurdle. I'm loading SimpleXML into an array, sorting it and then echoing it into the page with grouping for the data.
I can get my group headings to display, sorted correctly, however when I try to add the sub-group data (which requires xpath to match attributes to the parent group), my output is just the first group heading. Not sure if it's the way I'm mixing array results with xpath or not but hopefully somebody here can spot the issue straight away.
Here is my XML:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE besteplist SYSTEM "example.dtd">
<besteplist>
<yearlist>
<year yid="y1">
<yearname>1995, Season 3</yearname>
</year>
<year yid="y2">
<yearname>1996, Season 4</yearname>
</year>
<year yid="y3">
<yearname>1997, Season 5</yearname>
</year>
<year yid="y4">
<yearname>1994, Season 2</yearname>
</year>
<year yid="y5">
<yearname>1993, Season 1</yearname>
</year>
</yearlist>
<eplist>
<ep yearid="y1" eid="e1">
<eptitle>The Third Episode</eptitle>
<eptnumber>3</eptnumber>
</ep>
<ep yearid="y2" eid="e2">
<eptitle>Bla bla bla</eptitle>
<eptnumber>21</eptnumber>
</ep>
<ep yearid="y2" eid="e3">
<eptitle>Rar rar rar</eptitle>
<eptnumber>39</eptnumber>
</ep>
<ep yearid="y2" eid="e4">
<eptitle>Tra la la</eptitle>
<eptnumber>45</eptnumber>
</ep>
<ep yearid="y3" eid="e5">
<eptitle>Donkey</eptitle>
<eptnumber>126</eptnumber>
</ep>
<ep yearid="y1" eid="e6">
<eptitle>SHOULD APPPEAR AS FIRST ONCE SORTED</eptitle>
<eptnumber>1</eptnumber>
</ep>
</eplist>
</besteplist>
I am looking to sort the group headers by yearname in ascending order and the subgroup results by eptnumber in ascending order.
Here is my PHP code so far:
<?php
$xml=simplexml_load_file("example.xml") or die("Error: Cannot create object");
function xsort(&$sorted_year, $child_name, $order=SORT_ASC)
{
$sort_proxy = array();
foreach ($sorted_year as $k => $node) {
$sort_proxy[$k] = (string) $node->$child_name;
}
array_multisort($sort_proxy, $order, $sorted_year);
}
$sorted_year = $xml->xpath('/besteplist/yearlist/year');
xsort($sorted_year, 'yearname', SORT_ASC);
$sorted_ep = $xml->xpath('/besteplist/eplist/ep');
xsort($sorted_ep, 'eptnumber', SORT_ASC);
foreach ($sorted_year as $season) {
echo "SEASON: " . $season->yearname . "<br>";
foreach ($sorted_ep->xpath("//ep[#yearid='$season[yid]']") as $episode) {
echo "EPISODE TITLE: " . $episode->eptitle . PHP_EOL . "<br>";
echo "EPISODE NUMBER: " . $episode->eptnumber . PHP_EOL . "<br>";
echo PHP_EOL . "<br>";
}
}
?>
This is my output before any sorting:
SEASON: 1995, Season 3
EPISODE TITLE: The Third Episode
EPISODE NUMBER: 3
EPISODE TITLE: SHOULD APPPEAR AS FIRST ONCE SORTED
EPISODE NUMBER: 1
SEASON: 1996, Season 4
EPISODE TITLE: Bla bla bla
EPISODE NUMBER: 21
EPISODE TITLE: Rar rar rar
EPISODE NUMBER: 39
EPISODE TITLE: Tra la la
EPISODE NUMBER: 45
SEASON: 1997, Season 5
EPISODE TITLE: Donkey
EPISODE NUMBER: 126
SEASON: 1994, Season 2
SEASON: 1993, Season 1
This is how it SHOULD appear:
SEASON: 1993, Season 1
SEASON: 1994, Season 2
SEASON: 1995, Season 3
EPISODE TITLE: SHOULD APPPEAR AS FIRST ONCE SORTED
EPISODE NUMBER: 1
EPISODE TITLE: The Third Episode
EPISODE NUMBER: 3
SEASON: 1996, Season 4
EPISODE TITLE: Bla bla bla
EPISODE NUMBER: 21
EPISODE TITLE: Rar rar rar
EPISODE NUMBER: 39
EPISODE TITLE: Tra la la
EPISODE NUMBER: 45
SEASON: 1997, Season 5
EPISODE TITLE: Donkey
EPISODE NUMBER: 126
Many thanks in advance if you can spot the problem or suggest improvements. Obviously this is sample/example data based on the same structure.
Sam
UPDATE
Still haven't managed to get this quite right and unable to spot which point I'm going wrong at. Best guess would be the xpath within the foreach statement, but I'm not familiar enough with this type of code to be able to spot it.
I've switched out xsort for sort_obj_arr as I assume it's a somewhat better function. Unfortunately I'm getting the exact same results as before. Here's my updated code:
<?php
$xml=simplexml_load_file("example.xml") or die("Error: Cannot create object");
function sort_obj_arr(& $arr, $sort_field, $sort_direction) {
$sort_func = function($obj_1, $obj_2) use ($sort_field, $sort_direction) {
if ($sort_direction == SORT_ASC) {
return strnatcasecmp($obj_1->$sort_field, $obj_2->$sort_field);
} else {
return strnatcasecmp($obj_2->$sort_field, $obj_1->$sort_field);
}
};
usort($arr, $sort_func);
}
$sorted_year = $xml->xpath('/besteplist/yearlist/year');
$field1 = 'yearname';
$direction1 = SORT_ASC;
sort_obj_arr($sorted_year, $field1, $direction1);
$sorted_ep = $xml->xpath('/besteplist/eplist/ep');
$field2 = 'eptnumber';
$direction2 = SORT_ASC;
sort_obj_arr($sorted_ep, $field2, $direction2);
foreach ($sorted_year as $season) {
echo "SEASON: " . $season->yearname . "<br>";
foreach ($sorted_ep->xpath("//ep[#yearid='$season[yid]']") as $episode) {
echo "EPISODE TITLE: " . $episode->eptitle . PHP_EOL . "<br>";
echo "EPISODE NUMBER: " . $episode->eptnumber . PHP_EOL . "<br>";
echo PHP_EOL . "<br>";
}
}
?>
Your code
foreach ($sorted_ep->xpath("//ep[#yearid='$season[yid]']") as $episode)
throws an error
Fatal error: Call to a member function xpath() on a non-object (...)
because $sorted_ep is an array, not a SimpleXml-object.
It makes no sense to get a sorted list of all <ep> in your XML. You need to select the episodes for a certain year, and then sort those:
foreach ($sorted_year as $season) {
echo "SEASON: " . $season->yearname . "<br><br>";
// first select episodes from a certain year
$episodes = $xml->xpath("//ep[#yearid='$season[yid]']");
// then sort those
sort_obj_arr($episodes, "eptnumber", SORT_ASC);
// now iterate and echo
foreach ($episodes as $episode) {
echo " EPISODE TITLE: " . $episode->eptitle . "<br>";
echo " EPISODE NUMBER: " . $episode->eptnumber . "<br><br>";
}
}
see it in action: https://eval.in/468571

Group variables and loop through them

When I just had single variables I used the compact array function to create an array containing variables and their values and looped through them, but now I have multiple variables in a 'group' to loop through:
$details_room_name_1
$details_room_photo_1
$details_room_capacity_seated_1
$details_room_name_2
$details_room_photo_2
$details_room_capacity_seated_2
$details_room_name_2
$details_room_photo_2
$details_room_capacity_seated_2
I want to loop through each 'GROUP' (room) of variables at a time
loop
echo room name
print_r room photo array
echo capacity
Using array is better (the best) solution for this task, but if the data structure has to be as you wrote (I donĀ“t know Wordpress), you can use st. like this ugly code.
<?php
$details_room_name_1 = 'room 1';
$details_room_photo_1 = 'photo 1';
$details_room_capacity_seated_1 = 1;
$details_room_name_2 = 'room 2';
$details_room_photo_2 = 'photo 2';
$details_room_capacity_seated_2 = 5;
$details_room_name_3 = 'room 3';
$details_room_photo_3 = 'photo 3';
$details_room_capacity_seated_3 = 8;
for ($i = 1; $i <= 10; $i++) {
if (!isset(${'details_room_name_' . $i})) continue;
echo 'room name: ' . ${'details_room_name_' . $i} . '<br>';
echo 'room photo: ' . ${'details_room_photo_' . $i} . '<br>';
echo 'room capacity: ' . ${'details_room_capacity_seated_' . $i} . '<br><br>';
}
/*
returns
room name: room 1
room photo: photo 1
room capacity: 1
room name: room 2
room photo: photo 2
room capacity: 5
room name: room 3
room photo: photo 3
room capacity: 8
*/

foreach loop - php - weird behavior [duplicate]

This question already has answers here:
PHP Foreach Pass by Reference: Last Element Duplicating? (Bug?) [duplicate]
(6 answers)
Closed 8 years ago.
I am new to PHP and I am experimenting
right now with some foreach loops in PHP.
I know that it is recommended to unset
the foreach loop variables after the loop.
I noticed that if I include the lines // 1 // and
// 2 //, this script prints the right thing.
...
Name: Rachel, Age: 56
Name: Grace, Age: 44
( It also prints the right thing if in the last loop, I use other
variable names like $n and $a instead of $name and $age.)
But if I comment lines // 1 // and // 2 // out, it prints:
Name: Lisa, Age: 28
Name: Jack, Age: 16
Name: Ryan, Age: 35
Name: Rachel, Age: 46
Name: Grace, Age: 34
Name: Lisa, Age: 38
Name: Jack, Age: 26
Name: Ryan, Age: 45
Name: Rachel, Age: 56
Name: Grace, Age: 56
Notice that 56 is printed two times.
Why does it behave that way?
I mean: what happens under the hood?
<?php
$employee_age = array();
$employee_age["Lisa"] = "28";
$employee_age["Jack"] = "16";
$employee_age["Ryan"] = "35";
$employee_age["Rachel"] = "46";
$employee_age["Grace"] = "34";
foreach( $employee_age as $name => $age){
echo "Name: $name, Age: $age <br />";
}
echo "<br>";
unset($age);
unset($name);
foreach( $employee_age as $name => &$age){
$age += 10;
}
// echo "<br>";
// unset($age); // 1 //
// unset($name); // 2 //
foreach( $employee_age as $name => $age){
echo "Name: $name, Age: $age <br />";
}
echo "<br>";
unset($age);
unset($name);
?>
If you var_dump($employee_age) before the second loop you'll notice that the last entry say &int instead of int. It is still a reference. It points to the last element (ignoring itself). And that is Rachel with 56.
Look into the manual's warning: http://pl.php.net/manual/en/control-structures.foreach.php
Reference of a $value and the last array element remain even after the foreach loop. It is recommended to destroy it by unset().
It's PHP's behavior of a referenced item.
Reason : I think this guy can explain better than me.
Just a little memo.
Alternatively, to fix this, you can add & to $age at your third foreach:
foreach( $employee_age as $name => &$age){
echo "Name: $name, Age: $age <br />";
}
Hm.. not sure why you unset,
simpler:
$employee_age = array(
"Lisa" => 28,
"Jack" => 16,
"Ryan" => 35,
"Rachel" => 46,
"Grace" => 34);
foreach( $employee_age as $name => $age){
echo "Name: $name, Age: $age <br />";
}
echo "<br>";
foreach( $employee_age as $name => $age){
$age2 = $age + 10; // (Don't think this is required)
echo "Name: $name, Age: $age2 <br />"; // Try with just $age+10
}
?>
Grace = 56 because your code is;
foreach( $employee_age as $name => &$age){
$age += 10;
}
Change it to
foreach( $employee_age as $name => $age){
$age += 10;
}
And Grace will 34 again.

PHP foreach if/else Issue

I've been struggling with the following code. What I'm trying to do is count the number of reviews based on the score. The information is being drawn from MYSQL and a calculation is being preformed before entering it to an array there will be a maximum of five results (after formatting). To be counted.
The code I have is as follows:
$myArray = str_split(554);
$newArray = array_count_values($myArray);
foreach ($newArray as $key => $value) {
$reviews_percentage = round($value/3*100);
if (array_key_exists("1",$newArray)) {
echo "$key - <strong>$value</strong> as a percent its : $reviews_percentage <br />";
}
else {
echo "1 - <strong>0</strong> as a percent its : 0 <br />";
}
if (array_key_exists("2",$newArray)) {
echo "$key - <strong>$value</strong> as a percent its : $reviews_percentage <br />";
}
else {
echo "2 - <strong>0</strong> as a percent its : 0 <br />";
}
if (array_key_exists("3",$newArray)) {
echo "$key - <strong>$value</strong> as a percent its : $reviews_percentage <br />";
}
else {
echo "3 - <strong>0</strong> as a percent its : 0 <br />";
}
if (array_key_exists("4",$newArray)) {
echo "$key - <strong>$value</strong> as a percent its : $reviews_percentage <br />";
}
else {
echo "4 - <strong>0</strong> as a percent its : 0 <br />";
}
if (array_key_exists("5",$newArray)) {
echo "$key - <strong>$value</strong> as a percent its : $reviews_percentage <br />";
}
else {
echo "5 - <strong>0</strong> as a percent its : 0 <br />";
}
}
Which is giving the following result:
1 - 0 as a percent its : 0
2 - 0 as a percent its : 0
3 - 0 as a percent its : 0
5 - 1 as a percent its : 50
5 - 1 as a percent its : 50
1 - 0 as a percent its : 0
2 - 0 as a percent its : 0
3 - 0 as a percent its : 0
4 - 1 as a percent its : 50
4 - 1 as a percent its : 50
I can see its running through the loop twice but cannot work out what I'm doing wrong.
Added Database Structure
|------
|id|date_created|date_updated|ip_address|status|element_3|element_4|element_5|element_6|element_7|element_8|element_9|
|------
|1|2012-06-21 15:22:57|2012-06-21 16:06:04|::1|1|19|10|10|10|10|10|10|
|2|2012-06-21 16:21:23|2012-06-21 16:21:40|::1|1|19|10|9|9|9|10|
|3|2012-06-21 18:14:56|2012-06-21 18:15:19|::1|1|18| 5|5|5|5|5|
UPDATED CODE
$result = mysql_query("SELECT * FROM ap_form_5 WHERE element_1='19'") or die(mysql_error());
$num_rows = mysql_num_rows($result);
while($profile_rows = mysql_fetch_array($result)) {
$feature1 = $profile_rows['element_4'];
$feature2 = $profile_rows['element_5'];
$feature3 = $profile_rows['element_6'];
$feature4 = $profile_rows['element_7'];
$feature5 = $profile_rows['element_8'];
$overalladd = $feature1+$feature2+$feature3+$feature4+$feature5;
$ratingsbar .= floor(round($overalladd/5/2, 15, PHP_ROUND_HALF_DOWN));
$myArray = str_split($ratingsbar);
$arrayCount = array_count_values($myArray);
}
function perc($total,$count){
$ans = (100/$total) * $count;
return($ans);
// this array is only being filled like this to to show my working out (your db will populate this)
$ratings[1]= $arrayCount[0]; // 1 star ratings - 2 votes
$ratings[2]= $arrayCount[1]; // 2 star rating - 1 votes
$ratings[3]= $arrayCount[2]; // 3 star rating - 2 votes
$ratings[4]= $arrayCount[3]; // 4 star rating - 0 votes
$ratings[5]= $arrayCount[4]; // 5 star rating - 5 votes
$total_votes = array_sum($ratings);
$i = 1;
foreach($ratings as $rating){
echo "Stars ".$i.": ".perc($total_votes,$rating)."% $ratings[$i]<br />";
$i ++;
}
?>
Which is now giving the following result
Stars 1: 0%
Stars 2: 0%
Stars 3: 50% 1
Stars 4: 0%
Stars 5: 50% 1
Give this a try?
<?php
$result = mysql_query("SELECT * FROM ap_form_5 WHERE element_1='19'") or die(mysql_error());
$num_rows = mysql_num_rows($result);
while($profile_rows = mysql_fetch_array($result)) {
$total_ratings_this_loop = 0; // empty this before looping
$ratings[1]= $profile_rows['element_4']; // assuming that this field contains 1 star ratings for this product
$ratings[2]= $profile_rows['element_5']; // assuming that this field contains 2 star ratings for this product
$ratings[3]= $profile_rows['element_6']; // assuming that this field contains 3 star ratings for this product
$ratings[4]= $profile_rows['element_7']; // assuming that this field contains 4 star ratings for this product
$ratings[5]= $profile_rows['element_8']; // assuming that this field contains 5 star ratings for this product
$total_ratings_this_loop = array_sum($ratings); // takes all of the ratings for this product and totals them from inside the array
$overalladd = $feature1 + $feature2 + $feature3 + $feature4 + $feature5;
echo "Product ID: 19, has the following ratings<br />";
$i = 1; // empty this before looping
foreach($ratings as $rating_count){
echo $i." star, Rating count: ".$rating.",Percentage:".perc($total_ratings_this_loop,$rating)."%<br />";
$i ++;
}
}
?>
Replace your code with below code and check :
$myArray = str_split($ratingsbar);
$newArray = array_count_values($myArray);
foreach ($myArray as $key => $value) {
$reviews_percentage = round($value/$num_rows*100);
if (array_key_exists("1",$myArray)) {
echo "$key - <strong>$value</strong> as a percent its : $reviews_percentage <br />";
}
else {
echo "1 - <strong>0</strong> as a percent its : 0 <br />";
}
if (array_key_exists("2",$myArray)) {
echo "$key - <strong>$value</strong> as a percent its : $reviews_percentage <br />";
}
else {
echo "2 - <strong>0</strong> as a percent its : 0 <br />";
}
if (array_key_exists("3",$myArray)) {
echo "$key - <strong>$value</strong> as a percent its : $reviews_percentage <br />";
}
else {
echo "3 - <strong>0</strong> as a percent its : 0 <br />";
}
if (array_key_exists("4",$myArray)) {
echo "$key - <strong>$value</strong> as a percent its : $reviews_percentage <br />";
}
else {
echo "4 - <strong>0</strong> as a percent its : 0 <br />";
}
if (array_key_exists("5",$myArray)) {
echo "$key - <strong>$value</strong> as a percent its : $reviews_percentage <br />";
}
else {
echo "5 - <strong>0</strong> as a percent its : 0 <br />";
}
}
What I'm trying to do is count the number of reviews based on the
score.
Please show us the database structure filled with minimized example data, and tell us what is your expected result according to that data.
OK, if you would like to create something like this:
then I demostrate, how I would do it, because I still does not understand your logic.
votes table (this means user U voted on product P with S stars):
user_id | product_id | star
1 1 5
2 1 5
3 1 4
4 1 1
sql query for total votes on product 1 is
SELECT star,COUNT(*) as C
FROM votes
WHERE product_id=1
GROUP BY star
the result of this is
star C
1 1
4 1
5 2
to write it out:
$rs = mysql_query("");//put query here
$stars_count = array();
$star_sum = 0;
while($r = mysql_fetch_assoc($rs))
{
$stars_count[$r['star']] = $r['C'];
$star_sum += $r['C'];
}
for($i=5;$i>=1;$i--)
echo "Product 1 was voted $i star: ".
(isset($stars_count[$i])? round($stars_count[$i]/$star_sum*100)."%":"0%").
" (".( isset($stars_count[$i])? $stars_count[$i] : 0 ).")<br>";
result:
Product 1 was voted 5 star: 50% (2)
Product 1 was voted 4 star: 25% (1)
Product 1 was voted 3 star: 0% (0)
Product 1 was voted 2 star: 0% (0)
Product 1 was voted 1 star: 25% (1)

Categories