I tried to use custom-made usort funciton. when I loaded 5 cell array this runned over 30 seconds and then threw a fatal error.
I tried to find if I've been made an infinite loop but didn't founded it.
array:
Array ( [0] => Array ( [Name] => iPhone 5s 32 GB [Price] => 0 [Description] => A new Apple Product [Image_URL] => [Business_ID] => 6 [Keywords] => ["iPhone","iPhone 5s","Apple","32 GB"] ) [1] => Array ( [Name] => iPhone 4s 32 G [Price] => 300 [Description] => Apple iPhone 4S [Image_URL] => [Business_ID] => 6 [Keywords] => ["iPhone 4S","iPhone","Apple","32 GB"] ) )
search:
$searchTerm = "iphone 5s";
code:
if (!empty($searchTerm)) {
$searchTermWords = explode(" ", $searchTerm);
usort($products, function($a, $b) use ($searchTermWords) {
$aArr = explode(" ", $a['Name']);
$bArr = explode(" ", $b['Name']);
$aKeywords = $a['Keywords'];
$bKeywords = $b['Keywords'];
//todo: explode description too.
$aCount = 0;
$bCount = 0;
for ($i = 0; $i < $searchTermWords; $i++) {
for ($j = 0; $j < $aKeywords; $j++) {
if (strpos($aKeywords[$j], $searchTermWords[$i]) !== false)
$aCount++;
}
for ($j = 0; $j < $aArr; $j++) {
if ($aArr[$j] == $searchTermWords[$i])
$aCount++;
}
for ($j = 0; $j < $bKeywords; $j++) {
if (strpos($bKeywords[$j], $searchTermWords[$i]) !== false)
$bCount++;
}
for ($j = 0; $j < $bArr; $j++) {
if ($bArr[$j] == $searchTermWords[$i])
$bCount++;
}
}
return $bCount - $aCount;
});
}
Error (after 30 seconds):
Fatal error: Maximum execution time of 30 seconds exceeded in /home/itay/public_html/tester.php(30) : eval()'d code on line 94
if it's imprtant for some reason everything is made from eval() function.
You get the Fatal Error because your script doesn't exit properly. There is a For loop that runs infinitly.
Your for() loops are checked against the elements itself and not the number of elements. Are you trying to loop for the number of element in the array ? If so, try to use the count($array) to return the number of elements in the array. Then use that count to loop using the foreach.
Related
I have a task of sorting an array of numbers in both ascending and descending order. The challenge is, I can't use the built-in sort function, but loop through the array with for-loops instead.
I am a total newbie when it comes to PHP and this task straight off baffles me. Here is the code I'm supposed to work with:
<?php
$arr = $_GET['arr'];
$table = explode(',', $arr);
$count = count($table);
// What I tried to work with, didn't get to work:
for ($i = 0; $i < $count; $i++) {
for ($j = $i + 1; $j < $count; $j++) {
if ($table[$i] > $table[$j]) {
$temp = $table[$i];
$table[$i] = $table[$j];
$table[$j] = $temp;
$asc = implode("," $temp);
}
}
}
echo "Ascending: $asc";
echo "Descending: $desc";
?>
Any clue why this doesn't run? At some point, I got the first (largest) number in the array with the echo, but don't really know what broke that either.
Move the line
$asc = implode(",", $table);
from its current location below the outer for loop and maybe add the line
$desc = implode(",", array_reverse($table));
to get the descending sort order.
Many ways to make it. One solution you will find in the code below. you will certainly notice that the sorting depends only on one operator. Therefore, you can build a function out of it by specifying the sorting as a parameter. function(array $array, string $sort) {}
DESC
$arr= array(112,21,130,140,2,42);
for($i=0; $i<count($arr)-1; $i++)
{
for($j=0; $j<count($arr)-1; $j++)
{
if($arr[$j] < $arr[$j+1]){
$temp= $arr[$j+1];
$arr[$j+1]= $arr[$j];
$arr[$j]= $temp;
}
}
}
print_r($arr);
Output:
Array
(
[0] => 140
[1] => 130
[2] => 112
[3] => 42
[4] => 21
[5] => 2
)
ASC
$arr= array(112,21,130,140,2,42);
for($i=0; $i<count($arr)-1; $i++)
{
for($j=0; $j<count($arr)-1; $j++)
{
if($arr[$j] > $arr[$j+1]){
$temp= $arr[$j+1];
$arr[$j+1]= $arr[$j];
$arr[$j]= $temp;
}
}
}
print_r($arr);
Output
Array
(
[0] => 2
[1] => 21
[2] => 42
[3] => 112
[4] => 130
[5] => 140
)
I am trying to push the output of a for loop into an array but I am not being able to do so. Following is the code that I have written:
<?php
$n = 14;
for ($i = 2; $i <= $n; $i++)
{
for ($j = 2; $j <= $n; $j++)
{
if ($i%$j == 0) // if remainder of $i divided by $j is equal to zero, break.
{
break;
}
}
if ($i == $j) //
{
$form = $i;
//echo $form;
$numArray = array();
array_push($numArray, $form); // Here I am trying to push the contents from the `$form` variable into the `$numArray`
print_r($numArray);
}
}
?>
The output that I obtain through this is:
Array ( [0] => 2 ) Array ( [0] => 3 ) Array ( [0] => 5 ) Array ( [0] => 7 ) Array ( [0] => 11 ) Array ( [0] => 13 )
Here, we see that the array index basically remains the same, so it has no scope for future use. So, how can I make this seem like as shown below:
Array ( [0] => 2 ) Array ( [1] => 3 ) Array ( [2] => 5 ) Array ( [3] => 7 ) Array ( [4] => 11 ) Array ( [5] => 13 )
Please note that, $n in the code can be any number less than 101 and greater than 1. Thank you for your precious time put into reading and trying to helping me out. :)
The $numArray should be declared once, not every time in the loop. And you can simply add value to the array by using expression like: $numArray[] = $i;
Try this code:
<?php
$numArray = array();
$n = 14;
for ($i = 2; $i <= $n; $i++) {
for ($j = 2; $j <= $n; $j++) {
if ($i % $j == 0) { // if remainder of $i divided by $j is equal to zero, break.
break;
}
}
if ($i == $j) {
$numArray[] = $i;
}
}
print_r($numArray);
I'm trying to get a count of how many instances of 'UnitSqFeet' are within a certain range.
For example how many instances are between 0 - 175, or 176 - 300.
Here is a part example of the array (it contains 46 in total).
Array (
[0] => Array ( [UnitNumber] => 1.03 [UnitSqFeet] => 60.75 )
[1] => Array ( [UnitNumber] => 1.04 [UnitSqFeet] => 160.39 )
[2] => Array ( [UnitNumber] => 1.05 [UnitSqFeet] => 231.55 )
[3] => Array ( [UnitNumber] => 1.06 [UnitSqFeet] => 280.24 )
)
The 'UnitSqFeet' is a string so I'm assuming it'll have to be converted somewhere in there.
I managed to get this working as below but it would only output this in the first cell of an html table and not the rest. After doing some research on here I understand it's because I was repeating the query for every cell and after the first it had already retrieved all the rows. Not sure if there's a solution whereby I can just reset the query?
$counter = 0;
while ($units = odbc_fetch_array($result)) {
$num = $units['UnitSqFeet'];
$float = (float)$num;
if ($float > 0 && $float < 175) {
count($float);
$counter++;
};
};
echo $counter;
Try as
$count = $count2 = 0;
$result = array();
foreach(array_column($arr,'UnitSqFeet') as $key => $value){
if(round($value) <= 170){
if(!isset($result['0-170'])) $result['0-170'] = $count++;
$result['0-170'] = $count++;
}else{
if(!isset($result['171-300'])) $result['171-300'] = $count2++;
$result['171-300'] = $count2++;
}
}
print_r($result);
Fiddle
Try it here: http://viper-7.com/ofozYB
<?php
$UnitSqFeet = array_column($array, 'UnitSqFeet');
$output = array_filter($UnitSqFeet, function ($var) {
return ( $var >= 70 && $var <= 250 ); // return if between 70 & 250
});
print_r($output);
echo "There is " . count($output) . " values in the selected range";
I need to draw a stacked bar graph for this array which should have 2 bars separated with a white-space of 2 years span (from year 1998 to 2000)
The Problem:
the first bar should be like,
*1998-1997* - *2 years gap* - *2000-2008*
The bars should merge shorter year-spans within like it did in taking 2000 from array0 and 2008 from array 1
Array
(
[comp_name] => C++
[parent_cat_name] => Information Technology
[sub_cat_name] => Programming
[total_years] => 6
[last_year] => 2006
[start_year] => 2000
)
Array
(
[comp_name] => .NET
[parent_cat_name] => Information Technology
[sub_cat_name] => Programming
[total_years] => 7
[last_year] => 2008
[start_year] => 2001
)
Array
(
[comp_name] => API
[parent_cat_name] => Information Technology
[sub_cat_name] => Programming
[total_years] => 1
[last_year] => 1998
[start_year] => 1997
)
You want to merge two array items, if they are adjacent according to some condition AND have some equality condition on some other fields.
You might do:
for(;;)
{
$merge = array();
$n = count($data);
for ($i = 0; empty($merge) && $i < $n-1; $i++)
{
for ($j = $i+1; empty($merge) && $j < $n; $j++)
{
// Are $i and $j congruent?
if ($data[$i]['parent_cat_name'] != $data[$j]['parent_cat_name'])
continue;
if ($data[$i]['sub_cat_name'] != $data[$j]['sub_cat_name'])
continue;
// Are $i and $j adjacent?
if ($data[$i]['last_year']+1 == $data[$j]['start_year'])
{
$merge = array($i, $j);
break;
}
if ($data[$j]['last_year']+1 == $data[$i]['start_year'])
$merge = array($j, $i);
break;
}
// They are congruent but not adjacent, try the next
}
}
// If we get to the end and find nothing mergeable, exit.
if (empty($merge))
break;
list($i, $j) = $merge;
// We add $j to $i
$data[$i]['last_year'] = $data[$j]['last_year']
$data[$i]['total_years'] += $data[$j]['total_years']
// We destroy $j
unset($data[$j]);
// Dirty renumber
$data = array_values($data);
// Now data has been modified, let's do this again.
}
What I need to accomplish is,
I have an array, 2 3 4 5 6 7 8 9 10
I need to check if any numbers in the array divides any other number in the array perfectly. (%=0) If yes, unset the the number.
Its over my head and I cant get it working and everything I tried gives me infinite loops and its making me ill. (lol)
I am not including any codes, because all I could come up with is a nested forloop which doesnt work :(
So here is a sample :
Input array :2 3 4 5 6 7 8
Output = 5 6 7 8
Any idea guys?
UPDATE:
Cracked the nut myself with bit more debugging. (Incase if that can be helpful for someone in future.)
// use array_unique, array_values and $size = sizeof($array)
for ($i = 0; $i < $size; $i++)
{
for ($j = $size - 1; $j > $i; $j--)
if ($numbers[$j] % $numbers[$i] == 0)
{
unset($numbers[$i]);
break;
}
}
I will not do this in real code, just because I think you want to do that yourself.
LoopA iterating the intput array:
LoopB iterating the input array:
check division of loopA value and loopB value, and add the value of loopA to a new array accordingly
End loopB
End loopA
Print the new array
Note: This is not complete, but it certainly should give you a start on how to continue.
For sorted ordered number
$arr = array(2,3,4,5,6,7,8,9,10,11,12,13,14);
$half_c = ceil(count($arr)/2) - 1;
$result_array = array_slice($arr, $half_c);
Edit: For random array you can cut half again, and iterate only first part of array. Prime number theory also can help to write faster algorithm for first part of array.
How about:
$arr = range(2,20);
$size = count($arr);
for ($i=0; $i<$size; $i++) {
for ($j=$size-1; $j>$i; $j--) {
if ($arr[$j]%$arr[$i]) continue;
unset($arr[$i]);
break;
}
}
print_r($arr);
output:
Array
(
[9] => 11
[10] => 12
[11] => 13
[12] => 14
[13] => 15
[14] => 16
[15] => 17
[16] => 18
[17] => 19
[18] => 20
)
Try this:
for($i = 0; $i < count($arr); $i++)
{
for($j = 0; $j < count($arr); $j++)
{
if($arr[$i] != $arr[$j] && $arr[$i] % $arr[$j] === 0)
{
unset($arr[$j);
break;
}
}
}