I am currently trying to play about with some PHP that will compare an array of words/phrases with a user provided word and then return just the word which has the highest percentage..
My code so far is (for the sake of testing):
<?php
$CRProductName = strtoupper("Product 30");
$XProdNames = array("Product 1","Product 2", "Product 300", "Not a product");
echo "Checking product matches for: ".$CRProductName."<br /><br />";
foreach ($XProdNames as $ProductName) {
similar_text($CRProductName,strtoupper($ProductName), $p);
echo "Percentage:".$p."%<br />";
}
?>
This outputs the following:
Checking product matches for: PRODUCT 30
Percentage:84.2105263158%
Percentage:84.2105263158%
Percentage:95.2380952381%
Percentage:60.8695652174%
Which is great and it works, however I would just like it to return the product name with the highest percentage in the results?
Can anyone advise on a good route for me to take?
I tried adding an IF statement to check the value of $p, but the highest percentage may differ every time.
I converted all to uppercase just to make sure it is marking the similarity by content and not by case.
Thanks,
<?php
$CRProductName = strtoupper("Product 30");
$XProdNames = array("Product 1","Product 2", "Product 300", "Not a product");
echo "Checking product matches for: ".$CRProductName."<br /><br />";
$bestMatch = array('score' => 0, 'name' => 'None');
foreach ($XProdNames as $ProductName) {
$p = 0;
similar_text($CRProductName,strtoupper($ProductName), $p);
echo "Percentage:".$p."%<br />";
if($p > $bestMatch['score'])
{
$bestMatch = array('score' => $p, 'name' => $ProductName);
}
}
print_r($bestMatch);
?>
you could always run simlar_text a few times in each loop and average the results as well if you're getting fluxing results.
It's very simple. Just use an if statement to check for the highest value in the foreach loop. then echo the highest value. Here's your code with the minor change:
<?php
$CRProductName = strtoupper("Product 30");
$XProdNames = array("Product 1","Product 2", "Product 300", "Not a product");
echo "Checking product matches for: ".$CRProductName."<br /><br />";
$pHighest = 0;
foreach ($XProdNames as $ProductName) {
similar_text($CRProductName,strtoupper($ProductName), $p);
if ($p > $pHighest) {
$pHighest = $p;
}
}
echo "Percentage:".$pHighest."%<br />";
?>
Related
I have some code that processes an array of values, each one with a value 1 or 0.
<?php
$GD_album = [
[$gdclock,1],
[$gdheart,1],
[$gdblue,1],
[$gdblack5th,0],
[$gdgreymarble,1],
[$gdblack7th,0]
];
$GD[have] = '';
foreach($GD_album as list($name, $own)) {if ($own === 1)echo $name;}
echo $GD[have];
?>
Each of my $gd*** variables draws a block of PHP and HTML code, and the foreach I have above will only draw the ones with a "1", and skip the ones with a 0. This works great.
What I'd like to do is have a piece of code that will add up each variable with a value of 1; for a total of 4. I'd also like some code to add up 0; for a total of 2. Then I would like to add those two results together for a total of 6.
I have tried the count() and array_sum() functions with little success. What I tried that gave me some results is:
<?php
$GD[h_total] = '';
foreach($GD_album as list($name, $own))
{if ($own === 1) echo count($own);}
echo $GD[h_total];
?>
<?php
$GD[w_total] = '';
foreach($GD_album as list($name, $own))
{if ($own === 0) echo count($own);}
echo $GD[w_total];
?>
This however, only outputs: "1111" and not "4". And "00", not "2", respectively. Ideally, some code that could count my 0's & 1's, also add them, and stylize as "Have 4/6" or "Need 2/6" would be best! Can anyone point me in the right direction? Thanks!
Try the code below:
<?php
$GD_album = [
['gdclock',1],
['gdheart',1],
['gdblue',1],
['gdblack5th',0],
['gdgreymarble',1],
['gdblack7th',0]
];
$GD['h_total'] = [];
foreach($GD_album as list($name, $own)){
if(isset($GD['h_total'][$own])){
$GD['h_total'][$own]++;
}else{
$GD['h_total'][$own] = 1;
}
}
echo 'total zeros: '. $GD['h_total'][0];
echo 'total ones: '. $GD['h_total'][1];
echo 'total: ' .array_sum($GD['h_total']);
The output:
total zeros: 2
total ones: 4
total: 6
I'm a bit of a beginner with PHP and am implementing a review aggregator system for a few products.
I have created the input fields and am outputting the results from these fields using this code:
{ echo '<div class="review1">Review 1: '; the_field('review1'); '</div>';}
{ echo '<div class="review2">Review 2: '; the_field('review2'); '</div>';}
{ echo '<div class="review3">Review 3: '; the_field('review3'); '</div>';}
{ echo '<div class="review4">Review 4: '; the_field('review4'); '</div>';}
{ echo '<div class="review5">Review 5: '; the_field('review5'); '</div>';}
I want to use PHP to calculate the average (mean) however the number I am using to calculate this is set to 5 as that is the total number of number fields I have. Here is the code I am using
{ echo (get_field('review1')+get_field('review2')+get_field('review3')+get_field('review4')+get_field('review5'))/5;}
The problem with this method is that sometimes the fields will not contain a value so the number to divide by would need to be 1, 2, 3 or 4 instead of 5 depending on the total number of review fields that have a value.
Essentially I need to replace "/5" with "/n" where "n" is the total number of fields with values.
Can anyone please assist?
Regards,
Peter
I would put the values into an array, then filter out non-numeric values, and then do the calculation of the average:
$array = [ 123, 45, null, 17, 236 ];
// $array = [ get_field('review1'), get_field('review2'), etc. ]
$values = array_filter($array, 'is_numeric');
$result = array_sum($values) / count($values);
echo $result; // Output: 105.25
$items = ['1','2','7','',''];
$average = calculateAverage($items);
echo $average;
function calculateAverage($items)
{
$total = 0;
$count = 0;
foreach($items as $item)
{
if(is_numeric($item))
{
$total += $item;
$count++;
}
}
return $total / $count;
}
If the number is empty, it will not add the number to the devider
I'm trying to get a list of values for the Manufacturer field, but I do not get anything other than a white screen, no bugs, everything seems to be right, but nothing works
<?php
function removeBomUtf8($s){
if(substr($s,0,3)==chr(hexdec('EF')).chr(hexdec('BB')).chr(hexdec('BF'))){
return substr($s,3);
}else{
return $s;
}
}
$url = "http://www.pureexample.com/backend/data/car-sale.json";
$content = file_get_contents($url);
$clean_content = removeBomUtf8($content);
$decoded = json_decode($clean_content);
while ($el_name = current($decoded)) {
if ($el_name == 'Manufacturer') {
echo key($decoded).'<br />';
}
next($decoded);
}
?>
$decoded is an array of objects (type StdClass): when you call current you are returning that object which has three properties: Manufacturer, Sold and Month. If you just want to print out the Manufacturer name, edit your code as follows:
while ($el_name = current($decoded)) {
echo $el_name->Manufacturer . '<br>';
next($decoded);
}
However, as one of the commenters mentioned, the current/next syntax is pretty obscure, and not as easy to follow. You'd be better off writing:
foreach($decoded as $el_name) {
echo $el_name->Manufacturer . '<br>';
}
Each entry in the $decoded array should be a stdclass object representation of something like
{
"Manufacturer": "Toyota",
"Sold": 1200,
"Month": "2012-11"
}
Going from your comment...
i expect to see all rows with Manufacturer part like 1 "Manufacturer": "Toyota", 2 "Manufacturer": "Ford"3 "Manufacturer": "BMW" etc
what you're probably after is
$manufacturers = array_map(function($el) {
return sprintf('"Manufacturer": "%s"', $el->Manufacturer);
}, $decoded);
echo '<ol><li>', implode('</li><li>', $manufacturers), '</li></ol>';
Demo ~ https://eval.in/866131
Alternatively, just loop over $decoded with a foreach...
?>
<ol>
<?php foreach ($decoded as $el) : ?>
<li>"Manufacturer": "<?= htmlspecialchars($el->Manufacturer) ?>"</li>
<?php endforeach ?>
</ol>
You are dealing with an Object, and to make it more simple, try running this to get the results you said you wanted:
<?php
function removeBomUtf8($s){
if(substr($s,0,3)==chr(hexdec('EF')).chr(hexdec('BB')).chr(hexdec('BF'))){
return substr($s,3);
}else{
return $s;
}
}
$url = "http://www.pureexample.com/backend/data/car-sale.json";
$content = file_get_contents($url);
$clean_content = removeBomUtf8($content);
$decoded = json_decode($clean_content);
foreach ($decoded as $car) {
echo "Manufacturer is: $car->Manufacturer" . "<BR>";
echo "Sold is: $car->Sold" . "<BR>";
echo "Month is: $car->Month" . "<BR>";
echo "<P>";
}
?>
Here is the output from the PHP code above:
Manufacturer is: Toyota
Sold is: 1200
Month is: 2012-11
Manufacturer is: Ford
Sold is: 1100
Month is: 2012-11
Manufacturer is: BMW
Sold is: 900
Month is: 2012-11
Manufacturer is: Benz
Sold is: 600
Month is: 2012-11
Manufacturer is: GMC
Sold is: 500
Month is: 2012-11
Manufacturer is: HUMMER
Sold is: 120
Month is: 2012-11
I have an ordered list which is 19 entries long (but could change and be more or less). I'm listing it on a drop down menu but because of its length the column is dropping below the fold of the page.
I'd like to create a separate column (ul or div) to either divide the list into 2 or 3 equally, or have set list sizes e.g. max 7 per list.
Any ideas? Current code:
<div id="colour" class="dropmenudiv">
<?php
$sql = "select * from rug_colours where id <> 0 and active = 1 order by name";
$rs = $database->query($sql);
$index = 0;
foreach($rs as $v) {
echo "<a href=\"//$base_url/?action=search&colour=".$v['id']."\" >".$v['name']."</a>";
}
?>
Try something along the lines of:
<div id="colour" class="dropmenudiv">
<?php
$sql = "select * from rug_colours where id <> 0 and active = 1 order by name";
$rs = $database->query($sql);
$column_height = 7;
echo "<div class='column'>";
foreach($rs as $idx => $v) {
echo "<a href=\"//$base_url/?action=search&colour=".$v['id']."\" >".$v['name']."</a>";
if($idx % $column_height) echo "</div><div class='column'>";
}
echo "</div>";
?>
and for equal split you might try this:
$max_column_height = 7;
$no_of_cols = ceil(count($rs) / $max_column_height);
$column_height = floor($count($rs) / $no_of_cols);
You should use index variable to divide it into 2 or 3 div.
Following is example to make it in three parts:
$index = 0;
foreach($rs as $v) {
if($index > 7){
$index = 0; // reset to zero. You can also seperate it by any tag div or ul if you want
}
echo "<a href=\"//$base_url/?action=search&colour=".$v['id']."\" >".$v['name']."</a>";
$index++;
}
For an evenly spread distribution, first divide the number of elements by 7 (or whichever maximum rows you want to allow), rounding upwards. This gives the number of columns. Then divide the number of elements by the number of columns, rounding upwards: this gives you the actual number of rows you need.
I like array_chunk for this purpose:
$maxRowCount = 7;
$colCount = ceil(count($rs) / $maxRowCount);
$chunkSize = ceil(count($rs) / $colCount);
foreach(array_chunk($rs, $chunkSize) as $column) {
echo "<div class='column'>\n";
foreach($column as $v) {
echo "<a href=\"//$base_url/?action=search&colour={$v['id']}\" >{$v['name']}</a>";
}
echo "</div>\n";
}
You can create array of columns based on current index in foreach() loop like
$abc = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
$cols = [];
$perCol = 7;
foreach($abc as $index => $val) {
$colInd = $index / $perCol;
$cols[$colInd][] = $val;
}
print_r($cols);
This will split data in $abc into 3 coluns by 7 items per column.
i have that code, and i want to limit the result to 10 max.
how can i do that?
<?php
$actors = rtrim($movie_info[0]->actors, ", ");
if(stristr($actors, ",")) {
$actors = explode(",", $actors);
array_walk($actors, 'add_url_on_tags', '/actor');
echo ul($actors, array("class" => "genres2"));
echo '<div style="clear:both;"></div>';
}elseif(!empty($actors)) {
echo ''.$actors.'<br />';
}else{
echo 'empty';
}
?>
thank for your help!
What you're looking for is $actors = array_slice($actors, 0, 10);
<?php
$actors = rtrim($movie_info[0]->actors, ", ");
if(stristr($actors, ",")) {
$actors = explode(",", $actors);
$actors = array_slice($actors, 0, 10);
array_walk($actors, 'add_url_on_tags', '/actor');
echo ul($actors, array("class" => "genres2"));
echo '<div style="clear:both;"></div>';
} elseif(!empty($actors)) {
echo ''.$actors.'<br />';
} else{
echo 'empty';
}
?>
you should probably do it in your SQL instead of only cherry picking your results via the code above.
select
*
from
yourTable
where
someColumn=SomeCondition
order by
someColumn
limit 10
^^ This is the clause to add.
Will only bring back the first ten results
you can then use it for pagination, by adding one more value like this:
limit 10,10
This will now bring back ten results, but skip the first ten (basically showing results 11-20