PHP for loop will affect the page load speed? - php

$categories = array("google","adobe","microsoft","exoot","yahoo");
$sql='google,exoot,adobe';//from mysql_query
$categs = explode(",",$sql);
for($x=0;$x<count($categs);$x++){
for($y=0;$y<count($categories);$y++){
if($categs[$x] == $categories[$y]){
$str .= $y.",";
}
}
}
echo str; // 0,3,1,
Will this code will affect page render time? Can I do it using any other fast methods?
Thanks in advance.

$str = implode(',', array_keys(array_intersect($categories, $categs)));

You can use array_intersect() to find the common items and then use implode() to construct a comma-separated list:
Str = implode(',', array_intersect($categories, $categs)) . ',';
Unless you're dealing with a large number of items (thousands) it won't affect page speed. The one issue is that this intersection is O(n2). Putting the values into keys could speed it up considerably as that changes lookup time from O(n) to near O(1) making the whole operation O(n).

yes it will since you are looping in a loop.
Best thing is to check with in array:
$categories = array("google","adobe","microsoft","exoot","yahoo");
$sql='google,exoot,adobe';//from mysql_query
$categs = explode(",",$sql);
$str = array();
foreach($categs as $id => $categs_check)
{
if(in_array($categs_check, $categories))
{
//its better to put it into a array and explode it on a later point if you need it with comma.
$str[] = $id;
}
}
I'm not completely sure what you are trying to do but it should be something like the above

I don't think that str_replace is a faster method than all the array functions but another possible solution is:
$categories = array("google","adobe","microsoft","exoot","yahoo");
$sql='google,exoot,adobe';//from mysql_query
foreach($categories as $i=> $c) {
$sql = str_replace($c, $i, $sql);
}

$arrCategories = array("google","adobe","microsoft","exoot","yahoo");
$sql='google,exoot,adobe';//from mysql_query
$arrCategs = explode(",",$sql);
$arrAns = array();
for($i = 0, $intCnt = count($arrCategs); $i <= $intCnt; $i++) {
if(in_array($arrCategs[$i],$arrCategories)) {
$arrAns[$arrCategs[$i]] = array_search($arrCategs[$i], $arrCategories);
}
}
print "<pre>";
print_r($arrAns);
print "</pre>";

Related

Counting multidimensional array rows and their respective elements?

I'm doing something that is perhaps too long and strange to explain, but basically I've mapped a string in a complex way into an array in a way to make them jumbled up. This is an example of how it would look:
field[26][25]='x';
field[24][23]='z';
field[28][29]='y';
Now that I've successfully jumbled up the string in exactly the way I wanted, I need to reconstruct the linear result.
So I need to take row 1 of the array, and loop through all the elements in this row to combine them into a string. Then do the same thing with row 2 and so on to create one massive linear string.
How do I count how many rows and elements in those rows I have? For the life of me I cant even begin to find how to do this for multid arrays.
Kind regards
#u_mulder's got a solid answer there. For the number of elements, you'd just say:
$total = 0;
foreach( $matrix as $row ) $total += count($row);
For the concatenation of elements, you'd just say:
$concat = '';
foreach( $matrix as $row ) $concat .= implode('', $row);
Bob's your uncle. But really, is there a valid use case for such a strange mashup?
$field[26][25]='x';
$field[24][23]='z';
$field[28][29]='y';
$field_string = '';
array_walk_recursive ( $field , function($item, $key) use (&$field_string){
if(!is_array($item)){
$field_string .= $item;
}
});
echo $field_string;
Honestly, this is a little confusing. I may need more info but let me know if this helps
You can start with an empty string and use two nested foreach to iterate over lines and items on each line and append each item to the string:
$result = '';
foreach ($fields as $row) {
foreach ($row as $item) {
$result .= $item;
}
}
Or you can replace the entire inner foreach with $result .= implode('', $row);.
You can even replace the outer foreach with a call to array_map() then implode() the array produced by array_map() into a string:
$string = implode(
'',
array_map(
function (array $items) {
return implode('', $items);
},
$fields
)
);

PHP From string to two variables

In my db there is a table that have some values like this[string]
100/100
50/100
40/80
7/70
I need to change this values in
100%
50%
50%
10%
How can i do this using only PHP/mysql code?
EDIT:this is the code:
foreach ($html->find('div.stat') as $status_raw){
$status = $tag_pic_raw->src;
$status = mysql_real_escape_string($status);
$data->query("INSERT IGNORE INTO `tb` (`value`) VALUES ('".$status."')");
}
I have used a DOM inspector to get info from another site
Used explode() combined with some math.
$str = '40/80';
$vals = explode('/', $str);
$percent = (($vals[0] / $vals[1]) * 100).'%';
echo $percent;
use explode() to divide up the values and then math them.
foreach($array as $val) // assuming all the (##/##) values are in an array
{
$mathProblem = explode("/", $val);
echo (intval($mathProblem[0]) / intval($mathProblem[1]) * 100)."%<br />";
}
You can set up a function similar to this:
function math($one)
{
$new = explode("/", $one);
$math = $new[0] / $new[1];
$answer = $math * 100;
return $answer."%";
}
Then every time you need to query something, you can do it simply by doing this:
foreach ($results as $r)
{
echo math($r);
}
This just makes it (I think) tidier and easier to read.
Use explode() :Returns an array of strings, each of which is a substring of string formed by splitting it on boundaries formed by the string delimiter( / in this case).
$arr=array('80/100','50/100','40/80');
foreach($arr as $str){
$values = explode('/',$str);
echo ((int)$values[0]/(int)$values[1])*100.'%<br/>';
}

Fastest way to combine thousands of arrays uniquely in PHP

I am getting data from a database. Each result looks something like this
ASDF-1234-JKL-F1-STUFF
There are 50,000 results. Each one is being exploded
$exploded = explode('-',$dash_delimited_datum);
// $exploded = array('ASDF','1234','JKL','F1','STUFF');
I tried this:
$data = array();
while($row = mysql_fetch_array($result) ){
$i++;
if($i > 99999) {
break;
}
$data = array_merge($data,explode('-',$row[0]));
}
But I hit the server timeout of 5 minutes with it.
And this didn't work at all:
while($row = mysql_fetch_array($result) ){
$i++;
if($i > 99999) {
break;
}
$data_parts = explode('-',$row[0]);
foreach($data_parts as $value) {
$data = array_push(($data,$value);
}
}
Unexpectedly, this worked, taking "only" 9 seconds, but I wonder if I can make it even faster:
while($row = mysql_fetch_array($result) ){
$i++;
if($i > 99999) {
break;
}
$data = array_unique(array_merge($data,explode('-',$row[0])));
}
EDIT: I came up with an solution that I thought would be the best one, at 800ms
Note that I used a "closure" (the anonymous function) to remove numeric keys and I assumed it was a drag on speed. But actually, removing it caused the script to timeout at 30s.
$data=array();
while($row = mysql_fetch_array($result) ){
$i++;
if($i > 99999) {
break;
}
$data_parts = array_flip(array_filter(explode('-',$row[0]),
function($value) {
if(is_numeric($value)) {
return false;
} else return true;
}));
$data = array_merge($data,$data_parts);
}
$data = array_keys($data);
sort($data);
Conclusions:
Every fast answer used tricks involving the array keys, rather than values. And the difference between my best answer and the two very fast answers below seems to be their use of foreach inside the while loop to assign values directly to the main $data array. PHP function calls are supposedly expensive, and this example seems to prove that they really are. Both of the best answers gave me results in under 300 milliseconds. My best answer only worked fast when I filtered out numeric values, otherwise it ran into 30 second server timeout.
So, I guess if you are processing massive amounts of data, use constructs and not functions whenever you can.
Note about the (yes I know they're deprecated) mysql functions
One answer suggested that I use mysql_fetch_assoc instead of mysql_fetch_array. Actually, mysql_fetch_row is supposed to be "fastest", but the change made absolutely no difference in the speed of page loading with this data set (about 48,000 results). I also tried using mysql_result. The PHP docs say that it's slower when retrieving multiple rows, and it is a lot slower.
This took 6.27 seconds to load, versus about 0.27 seconds (270 milliseconds) for the similarly structured best answer.
$i=0;
while($data_parts = explode('-',mysql_result($result,$i,0)) ){
$i++;
if($i > 99999) {
break;
}
foreach($data_parts as $value) {
$data[$value] = 1;
}
}
$data = array_keys($data);
In order to speed the process, instead of using expensive functions to deal with arrays, using an associative array (hash) to ensure unique values should have the whole faster
$i = 0;
$hash = array();
while($row = mysql_fetch_array($result)) {
$i++;
if($i > 99999) {
break;
}
foreach (explode('-', $row[0]) as $s) {
$hash[ $s ] = 1;
}
}
This way, all strings are uniquely stored in an associative array (called hash).
The resulting array is $hash keys ( $data )
$data = array_keys( $hash );
print_r( $data );
How about this (I removed your counter, but you can add back in if its necessary):
$data = array();
$i = 0;
while($row = mysql_fetch_array($result) )
{
$data_parts = explode('-',$row[0]);
foreach($data_parts as $value)
{
if (!isset($data[$value]))
$data[$value] = $i++;
}
}
$data = array_flip($data);
I can't really benchmark on my computer, so if its slower than your implementations, let me know!
Try using mysql_fetch_assoc instead of mysql_fetch_array. mysql_fetch_array returns both numeric and associative indexes (effectively doubling the size of your array). In addition, try to use a little functions as possible within your while loop. For instance, if you iterate through 50,000 elements, and have 3 function calls in each iteration, thats 150,000 times the functions are called.
In addition, why not strip duplicates before even passing the result to the loop?
SELECT someField
FROM someTable
GROUP BY someField
HAVING COUNT(someField)>0
Once running that, run your loop
$data = array();
while($row = mysql_fetch_assoc($result) ){
$i++;
if($i > 99999) {
break;
}
$data[] = explode('-',$row[0]);
}

Elegant Method of Inserting Code Between Loops

In web development, I often find I need to format and print various arrays of data, and separate these blocks of data in some manner. In other words, I need to be able to insert code between each loop, without said code being inserted before the first entry or after the last one. The most elegant way I've found to accomplish this is as follows:
function echoWithBreaks($array){
for($i=0; $i<count($array); $i++){
//Echo an item
if($i<count($array)-1){
//Echo "between code"
}
}
}
Unfortunately, there's no way that I can see to implement this solution with foreach instead of for. Does anyone know of a more elegant solution that will work with foreach?
I think you're looking for the implode function.
Then just echo the imploded string.
The only more elegant i can think of making that exact algorithm is this:
function implodeEcho($array, $joinValue)
{
foreach($array as $i => $val)
{
if ($i != 0) echo $joinValue;
echo $val;
}
}
This of course assumes $array only is indexed by integers and not by keys.
Unfortunately, I don't think there is any way to do that with foreach. This is a problem in many languages.
I typically solve this one of two ways:
The way you mention above, except with $i > 0 rather than $i < count($array) - 1.
Using join or implode.
A trick I use sometimes:
function echoWithBreaks($array){
$prefix = '';
foreach($array as $item){
echo $prefix;
//Echo item
$prefix = '<between code>';
}
}
If more elaborate code then an implode could handle I'd use a simple boolean:
$looped = false;
foreach($arr as $var){
if($looped){
//do between
}
$looped = true;
//do something with $var
}

How to get numeric key of new pushed item in PHP?

$arr[] = $new_item;
Is it possible to get the newly pushed item programmatically?
Note that it's not necessary count($arr)-1:
$arr[1]=2;
$arr[] = $new_item;
In the above case,it's 2
end() do the job , to return the value ,
if its help to you ,
you can use key() after to petch the key.
after i wrote the answer , i see function in this link :
http://www.php.net/manual/en/function.end.php
function endKey($array){
end($array);
return key($array);
}
max(array_keys($array)) should do the trick
The safest way of doing it is:
$newKey = array_push($array, $newItem) - 1;
You can try:
max(array_keys($array,$new_item))
array_keys($array,$new_item) will return all the keys associated with value $new_item, as an array.
Of all these keys we are interested in the one that got added last and will have the max value.
You could use a variable to keep track of the number of items in an array:
$i = 0;
$foo = array();
$foo[++$i] = "hello";
$foo[++$i] = "world";
echo "Elements in array: $i" . PHP_EOL;
echo var_dump($foo);
if it's newly created, you should probably keep a reference to the element. :)
You could use array_reverse, like this:
$arr[] = $new_item;
...
$temp = array_reverse($arr);
$new_item = $temp[0];
Or you could do this:
$arr[] = $new_item;
...
$new_item = array_pop($arr);
$arr[] = $new_item;
If you are using the array as a stack, which it seems like you are, you should avoid mixing in associative keys. This includes setting $arr[$n] where $n > count($arr). Stick to using array_* functions for manipulation, and if you must use indexes only do so if 0 < $n < count($arr). That way, indexes should stay ordered and sequential, and then you can rely on $arr[count($arr)-1] to be correct (if it's not, you have a logic error).

Categories