How do I count comma-separated values in PHP? - php

I have a variable holding values separated by a comma (Implode), and I'm trying to get the total count of the values in that variable. However. count() is just returning 1.
I've tried converting the comma-separated values to a properly formatted array which still spits out1.
So here is the quick snippet where the sarray session is equal to value1,value2,value3:
$schools = $_SESSION['sarray'];
$result = count($schools);

You need to explode $schools into an actual array:
$schools = $_SESSION['sarray'];
$schools_array = explode(",", $schools);
$result = count($schools_array);
if you just need the count, and are 100% sure it's a clean comma separated list, you could also use substr_count() which may be marginally faster and, more importantly, easier on memory with very large sets of data:
$result = substr_count( $_SESSION['sarray'], ",") +1;
// add 1 if list is always a,b,c;

Should be
$result = count(explode(',',$schools));

Actually, its simpler than that:
$count = substr_count($schools, ',') + 1;

If there is sarray key set in session array, the count will return 1 for an empty string as well.
$session = array('sarray' => '');
$count = count(explode(',', $session['sarray']));
echo $count;
// => 1
So, if you want to count the number of items in the array, you will have to add an additional check for empty.
$session = array('sarray' => '');
$count = !empty($session['sarray']) ? count(explode(',', $session['sarray'])) : 0;
echo $count;
// => 0
Now, let's check if this works with items inside sarray.
$session = array('sarray' => 'foo, bar');
$count = !empty($session['sarray']) ? count(explode(',', $session['sarray'])) : 0;
echo $count;
// => 2
Hope this helps.

$schools = $_SESSION['sarray'];
$array = explode(',', $schools); array_walk($array, 'trim');
$count = count($array);
The array_walk($array, 'trim') will remove any trailing space in elements value. :)

Related

Array with only 10 most recent values

I have an array with multiple elements. I want to keep only the 10 most recent values. So I am reversing the array in a loop, checking if the element is within the first 10 range and if not, I unset the element from the array.
Only problem is that the unset does not work. I am using the key to unset the element, but somehow this does not work. The array keeps on growing. Any ideas?
$currentitem = rand(0,100);
$lastproducts = unserialize($_COOKIE['lastproducts']);
$count = 0;
foreach(array_reverse($lastproducts) as $key => $lastproduct) {
if ($count <= 10) {
echo "item[$key]: $lastproduct <BR>";
}
else {
echo "Too many elements. Unsetting item[$key] with value $lastproduct <BR>";
unset($lastproducts[$key]);
}
$count = $count + 1;
}
array_push($lastproducts, $currentitem);
setcookie('lastproducts', serialize($lastproducts), time()+3600);
I'd use array_slice ( http://php.net/array_slice ) perhaps like:
$lastproducts = unserialize($_COOKIE['lastproducts']);
// add on the end ...
$lastproducts[] = $newproduct;
// start at -10 from the end, give me 10 at most
$lastproducts = array_slice($lastproducts, -10);
// ....
You can use array_splice($input, $offset) function for this purpose.
$last_items_count = 10;
if(count($lastproducts) >= $last_items_count) {
$lastproducts = array_splice($lastproducts, count($lastproducts) - $last_items_count);
}
var_dump($lastproducts);
I hope this code helps.
For more information, here is the documentation:
http://php.net/manual/en/function.array-splice.php
I think a better way to select last 10 is:
$selection = array();
foreach(array_reverse($lastproducts) as $key => $lastproduct) {
$selection[$key] = $lastproduct;
if (count($selection)>=10) break;
}
Finally, $selection will have last 10 (or less) products.
Works great using array_splice and array_slice, thanks! :)
$lastproducts = unserialize($_COOKIE['lastproducts']);
// remove this product from array
$lastproducts = array_diff($lastproducts, array($productid));
// insert product on first position in array
array_splice($lastproducts, 0, 0, $productid);
// keep only first 15 products of array
$lastproducts = array_slice($lastproducts, 0, 15);

php sum the values seperated by special character

I need to sum the result set values separated by "|" inside the loop eg. set of values 10|2, 6|2, 8|1 should result in 24|5.
here is my code:
<?php
$fromdate="2016-03-31";
$todate="2016-03-31";
$TAG="1";
$con = mysqli_connect("XXXXX","XX","XXX","XXX");
$query = mysqli_query($con, "CALL sp_Android_Online_Dashboard('$fromdate', '$todate','$TAG')") or die("Query fail: " . mysqli_error());
$Totfiles = 0;
$file_minutes = 0;
$Tot_minutes=0;
$Pending=0;
while(($row = mysqli_fetch_array($query)))
{
$Totfiles +=$row["Totfiles"];
$file_minutes +=$row["file_minutes"];
$Pending =str_replace(array("/"),"|",$row["Pending"]); //need to sum all the values separated by "|"
$Tot_minutes +=$row["Tot_minutes"];
}
$response["Details"]['Totfiles'] = $Totfiles;
$response["Details"]['file_minutes'] = $file_minutes;
$response["Details"]['Pending'] = $Pending;
$response["Details"]['Tot_minutes'] = $Tot_minutes;
echo json_encode($response);
?>
$row["Pending"] contains the values which are to be summed
result am getting now,
"Pending":"16|9"
"Pending":"11|3"
"Pending":"6|2"
my expected result,
"Pending":"33|14"
This is what you are aiming at i think, you make an array first containing 2 values, on each iteration through the loop you add the new values to them and at the end you can implode it into a string again
// Start with an array containing 0 twice
$Totalpending = [0,0];
while(($row = mysqli_fetch_array($query)))
{
// On each loop we add the left value to the first value in the array and the right value to the second value in the array
$tmp = explode("|", $row['Pending']);
$Totalpending[0] += $tmp[0];
$Totalpending[1] += $tmp[1];
$Totfiles +=$row["Totfiles"];
$file_minutes +=$row["file_minutes"];
$Pending =str_replace(array("/"),"|",$row["Pending"]); //need to sum all the values separated by "|"
$Tot_minutes +=$row["Tot_minutes"];
}
// if you want to format the values in the same way again, although an array is much easier to handle, but it's up to you.
$stringTotalpending = implode('|',$Totalpending);
the string value you want will then be in $stringTotalpending
So Firstly, we need to explode the values from $row["Pending"].
$arr = explode("|", $row["Pending"]);
Now use a loop to add those two numbers:
$temp = 0;
for($i = 0; $i < count($arr); $i++){
$temp += (int) $arr[$i];
}
Now the $temp would contain the result.
As simple as that.
And also as a side note, your code is vulnerable to SQL-Injection attacks.
What about evaling the same string with '|' replaced by '+' ?
eval('$result = ' . str_replace('|', '+', preg_replace('/[^0-9|]/', '', $row["Pending"])) . ';');
echo "$result\n";
Note preg_replace() to sanitize input. Can be avoided if input is already sanitized

Explode and then merge arrays

I have two strings, one containing names separated by commas and the other containing email addresses separated by commas.
I now want my end result to replicate the behaviour as if I had gotten those values from the database with a:
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
echo $row['name'].'<br />'.$row['email'];
}
So I have for example these strings:
email1#domain.com,email2#domain.com,email3#domain.com
and
name1,name2,name3
And can then explode these into value arrays. Now, after exploding them,
I want to be able to make a loop where in each loop I can get $name[0] and $email[0] together, and $name[1] and $email[1] together, etc.
How can I merge the two arrays (after exploding them) and get the data for each datapair (name and email) in a loop?
So if I understood you right, you are converting your strings (lets call them email, and name) too two arrays (lets call them arrEmail, and arrName) and now you want to get a array with the merged datasets.(creating the arrays should be easy if not check this out: manual for php explode function)
If so I would create a for loop based on the length of your two arrays. In the loop I would extract value i of arrEmail and arrName, and put the information into an two-dimensional array. Maybe something like this:
It should work but I didn't test it for ages so if not leave me a comment.
<?php
$arrEmail = array();
$arrName = array();
$arrGoal;
$arrLength = count($arrName);
//creating two-dimensional Array
for($i = 0; $i < $arrLength; $i++){
$arrGoal[$i] = array($arrName[$i], $arrEmail[$i]);
//should look something like this ((name, email),(name, email)…)
}
$arrGoalLength = count($arrGoal);
//accessing Array
//1. dimension
for($i = 0; $i < $arrGoalLength; $i++){
//2. dimension
//Variables should be global (but aren't)
$newName = $arrGoal[$i][0];
$newEmail = $arrGoal[$i][1];
}
?>
I think you want something like this:
$output = array();
for ($i = 0; $i < count($names); $i++) {
$output[] = $names[$i] . ' ' . $emails[$i];
}
print_R($output);
$emails = 'email1#domain.com,email2#domain.com,email3#domain.com';
$emails = explode(',', $emails);
$names = 'name1,name2,name3';
$names = explode(',', $names);
and you can use array_combine() as follow :
$combined = array_combine($names, $emails);
foreach($combined as $name => $email){
echo $name, ' : ', $email, '<br/>';
}
I think you should use the built in explode function wich will allow you to turn a string to an array by spliting it using a delimiter (comma) :
$names = explode(",",$row['name']);
$email = explode(",",$row['email']);
for merging them you should use something like this
$Array = array();
for ($j = 0; $j < count($names); $j++) {
$Array[] = [$names[$j],$email[$j]];
}
This is kind a related with your question, but only if you like to access the value by a key(e.g. access the name by email provided):
<?php
$emails = 'email1#gmail.com,email2#gmail.com,email3#gmail.com';
$names = 'name1,name2,name3';
$arrayEmails = explode(',',$emails);
$arrayNames = explode(',',$names);
$result = array_combine( $arrayEmails, $arrayNames);
print_r($result);
?>

multi-dimension array duplicate - performance

What is the best way to check if an multi-dimension array contains 2 or more equal value and only return the first one .
ex : i have an array of people that contain
[0][firstName] = 'John';
[0][lastName] = 'Doe';
[N][firstName] = 'Marco';
[N][lastName] = 'Polo';
[120][firstName] = 'John';
[120][lastName] = 'Doe';
Should detect that the index 120 is a duplicate and remove it .
I'm looking for the best performance , i don't want to loop on the array and check every time if i have the value or not .
Is there something faster ?
It is the element distinctness problem which is basically O(NlogN) via sorting and iterating (after sorting, duplicates will be adjacent to each other - so easy to detect them)
However, it can be done also in O(N) on average and with O(N) additional space by storing all elements to a hash table while iterating, and breaking if an element already exists.
You might also want to store the original index of each element if you will later need it (and don't use the index as key).
pseudo code:
map <- empty hash map
for each element e with idx i in list (in ascending order of i):
if (map.contains(e)):
e is a dupe, the first element is in index map.get(e)
else:
map.add(e,i)
You can try
// Generate Possible name with duplicate
$names = array("John","Doe","Polo","Marco","Smith");
$array = array();
for($i = 0; $i < 20; $i ++) {
$key = mt_rand(0, 1000);
$array[$key]["firstName"] = $names[array_rand($names)];
$array[$key]["lastName"] = $names[array_rand($names)];
}
// Start Sorting process
ksort($array);
// Start Storage
$data = $hash = array();
// Loop and porpulate new array
foreach ( $array as $k => $v ) {
$h = sha1($v['firstName'] . $v["lastName"]);
isset($hash[$h]) or $data[$k] = $v and $hash[$h] = 1;
}
var_dump($data);

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