There is an array :
$ret = array();
... query execution
$ret['cnt'] = $this->db->num_rows(); // total number of database records
$i = 0;
while ( $this->db->next_record() ) { // fetching database records
$ret[$i]["user_id"] = $this->db->f('user_id') ;
$ret[$i]["user_login"] = stripslashes($this->db->f('user_login'));
$i++;
}
Now I want to remove from this array the element whose "user_id" is equal to a particular value :
if ($ret['cnt'] > 0) {
for ($i=0; $i<$ret['cnt']; $i++) {
if ($ret[$i]['user_id'] == $_SESSION[CODE_USER]) {
unset($ret[$i]);
break;
}
}
}
After printing the array I noticed that the element 0 is not in the array , this is what I am expecting. The only problem is now how to rearrange the array elements so that it will be compact again without any hole in its elements because the element 0 is not present ?
Use array_values:
$ret = array_values($ret);
http://php.net/manual/en/function.array-values.php
Or instead of using the 0th index. You could just grab the first element with reset.
http://php.net/manual/en/function.reset.php
array_values is probably the simplest way to reset keys.
if ($ret['cnt'] > 0) {
for ($i=0; $i<$ret['cnt']; $i++) {
if ($ret[$i]['user_id'] == $_SESSION[CODE_USER]) {
$ret = array_slice($ret,$i,1);
break;
}
}
}
array_slice will also strip away a section of the array and re-index as necessary.
Related
I'm trying to remove an object from an array if one of his properties is null or empty, this is the code.
The array has been sorted using this function:
function sortArray($c1, $c2)
{
return ($c1->propertyToCheck < $c2->propertyToCheck);
}
In case it changes anything.
$myArray = array();
...
// Add values to the array here
...
usort($myArray,"sortArray");
for($i = 0; $i < count($myArray ); $i++)
{
if(empty($myArray[$i]->propertyToCheck))
{
unset($myArray[$i]);
// var_dump($myArray[$i]) returns NULL
}
}
echo json_encode($myArray);
// Returns the entire array, even with the values that shouldn't be there.
The code is inside a function but the array is created inside said function.
I'm using echo json_encode($myArray) to send the value back in AJAX, but the array sent is the entire array with every object inside it.
The count($myArray) is the "problem".
Once the unset() is "reached" there is one element less in the array and therefore the next call to count($myArray) will return n-1 of the previous iteration -> your loop doesn't get to the end of the array.
You have at least three choices (in ascending order of my preference)
a)
$maxIdx = count($myArray);
for($i = 0; $i < $maxIdx; $i++) {
b)
foreach( $myArray as $key=>$obj ) {
if(empty($obj->propertyToCheck)) {
unset($myArray[$key]);
c)
$myArray = array_filter(
$myArray,
function($e) {
return !empty($e->propertyToCheck);
}
);
(...and many more)
see also: http://docs.php.net/array_filter
I asked a similar question earlier but I couldn't get a clear answer to my issue. I have a function "isParent" that gets 2 pieces of data. Each 1 of the 2 gets a string separating each value with a , or it just gets a plain int and then checks if the first value given is a parent of the second.
I pull the 2 bits of data in and explode them but when I go through my nested for loop and try to test
$toss = $arr1[$i];
print_r($toss);
It comes up blank. I have no idea what the issue is: Here is the full code of the function...
function isParent($parent, $child)
{
$parentArr = explode(',', $parent);
$childArr = explode(',',$child);
//Explode by Comma here. If array length of EITHER parentArr or childArr > 1 Then throw to an Else
if(count($parentArr) <= 1 && count($childArr) <= 1) //If explode of either is > 1 then ELSE
{
$loop = get_highest_slot(15);
for($i = $loop; $i > 0; $i--)
{
$temp = get_membership_from_slot($i,'id_parent','id_child');
if($temp['id_parent'] == $parent && $temp['id_child'] == $child)
{
return 1;
}
}
}
else //set up a for loop in here so that you traverse each parentArr value and for each iteration check all child values
{
$i = count($parentArr);
$c = count($childArr);
for(;$i >=0;$i--) //Loop through every parent
{
for(;$c >=0;$c--)
{
echo '<br>$i = ';
print_r($i);
echo '<br><br>Parent Arr at $i:';
$toss = $parentArr[$i];
echo $toss;
echo '<br>';
print_r($childArr);
echo '<br><br>';
if(isParent($parentArr[$i],$childArr[$c])) //THIS CAUSES AN INFINITE YES! Learn how to pull an array from slot
{
return 1;
}
}
}
}
return 0;
}
You are missing some code for the slot procedures. Apart from that, you probably need to use a different variable for the inner for loop. because $c will be 0 after the first iteration of $i.
Thanks for the help! The issue was in the recursive call back to the top of the function. It was tossed empty slots and when comparing 2 empty slots it returned a false positive. A quick !empty() check fixed it.
Given associated array of messages (each 2nd level array is a result of different sql query):
$tmp = array(
'type1'=>array ('key'=>'value'),
'type2'=>array(1=>1,2=>2,3=>3,4=>'men',5=>'pro'),
'type3'=>array(1=>1,2=>2,3=>3,'test'=>'website','creation'=>'www.prost.pro',8,9,10=>array('3dlevel','subarray'),11,12,13,14,15,16,18,18,19,20),
'type4'=>array(1,2,3)
);
I need to display only 8 of them.
And they have to represent all and every types (1st level values) of messages.
So I need to call:
$total_quantity_limit = 8;
var_dump(array_assoc_truncate($tmp, $total_quantity_limit));
And to get something like:
array(
'type1'=>array('key'=>'value'),
'type2'=>array(1=>1,2=>2,3=>3),
'type3'=>array(1=>1,2=>2),
'type4'=>array(1,2)
);
what have to be inside array_assoc_truncate()?
From the example output I see, looks like you want something like:
<?php
$tmp = array(
'type1'=>array('key'=>'value'),
'type2'=>array(1=>1,2=>2,3=>3,4=>'men',5=>'pro'),
'type3'=>array(1=>1,2=>2,3=>3,'test'=>'website','creation'=>'www.prost.pro',8,9,10,11,12,13,14,15,16,18,18,19,20),
'type4'=>array(1,2,3)
);
function array_assoc_truncate($array, $limit){
$depth = 0;
$count = 0;
$out = array();
//outter loop
while($count < $limit){
//boolean, was a key found
$found = false;
//loop through each top level key
foreach($array as $k=>$v){
//if the value is an array
if(is_array($v)){
//get the keys
$keys = array_keys($v);
//if a keys exists at this depth
if(isset($keys[$depth])){
//get the key
$key = $keys[$depth];
//if $out doesn't have the top level key yet, add it
if(!isset($out[$k])){
$out[$k]=array();
}
//set the value under $key in $out
$out[$k][$key]=$v[$key];
//increment our count
$count++;
//a key was found at this depth
$found=true;
}
}
//if we hit our limit, break
if($count >= $limit){
break;
}
}
//if no key was found at this depth, there is no more depth to search
if(!$found){
break;
}
//go down one more level
$depth++;
}
//return the output array
return $out;
}
echo '<hr><h1>Before:</h1>';
var_dump($tmp);
echo '<hr><h1>After:</h1>';
adump(array_assoc_truncate($tmp, 8));
http://codepad.viper-7.com/a8cF5J
However, as hinted at above, if this is from the result of a query, you could/should probably restructure your query to give you better results.
I have a php array
How can I compare all values of this array and filter out values based on custom logic (callback function maybe).
Essentially, I want to compare each array value with every other value within the array and based on some custom logic, either keep the value or remove it from the array
Thanks
Probably you have to do it manually:
function your_callback($a, $b)
{
return $a != $b;
}
$array = array(/** Your array here... **/);
$n = count($array);
$filtered = array();
for($i = 0; $i < $n; $i++)
{
$ok = true;
for($j = 0; $j < $n; $j++)
{
if($j != $i && !your_callback($array[$i], $array[$j])
{
$ok = false;
break;
}
}
if($ok)
array_push($filtered, $array[$i]);
}
unset($array);
$array = $filtered;
This example will filter unique values of array for example; change your_callback definition to implement other logic.
You can call array_map, passing your callback as the first argument, and passing your array twice, as the second and the third argument. In the callback function, you loop through the "second" array and return the element if you want.
If you are looking to compare values of one array with values of another array in sequence then my code is really simple: check this out it will work like this:
if (1st value of array-1 is equal to 1st value of array-2) { $res=$res+5}
if($_POST){
$res=0;
$r=$_POST['Radio1']; //array-1
$anr=$_POST['answer']; //array-2
$arr=count($r);
for($ac=0; $ac<$arr; $ac++){
if($r[$ac]==$anr[$ac]){
$res=$res+5;
}
}
echo $res;
}
I have a database table with images that I need to display. In my view, I'd like to display UP TO 10 images for each result called up. I have set up an array with the 20 images that are available as a maximum for each result (some results will only have a few images, or even none at all). So I need a loop that tests to see if the array value is empty and if it is, to move onto the next value, until it gets 10 results, or it gets to the end of the array.
What I'm thinking I need to do is build myself a 2nd array out of the results of the test, and then use that array to execute a regular loop to display my images. Something like
<?php
$p=array($img1, $img2.....$img20);
for($i=0; $i<= count($p); $i++) {
if(!empty($i[$p])) {
...code
}
}
?>
How do I tell it to store the array values that aren't empty into a new array?
you could do something like:
$imgs = array(); $imgs_count = 0;
foreach ( $p as $img ) {
if ( !empty($img) ) {
$imgs[] = $img;
$imgs_count++;
}
if ( $imgs_count === 10 ) break;
}
You can simply call array_filter() to get only the non-empty elements from the array. array_filter() can take a callback function to determine what to remove, but in this case empty() will evaluate as FALSE and no callback is needed. Any value that evaluates empty() == TRUE will simply be removed.
$p=array($img1, $img2.....$img20);
$nonempty = array_filter($p);
// $nonempty contains only the non-empty elements.
// Now dow something with the non-empty array:
foreach ($nonempty as $value) {
something();
}
// Or use the first 10 values of $nonempty
// I don't like this solution much....
$i = 0;
foreach ($nonempty as $key=>$value) {
// do something with $nonempty[$key];
$i++;
if ($i >= 10) break;
}
// OR, it could be done with array_values() to make sequential array keys:
// This is a little nicer...
$nonempty = array_values($nonempty);
for ($i = 0; $i<10; $i++) {
// Bail out if we already read to the end...
if (!isset($nonempty[$i]) break;
// do something with $nonempty[$i]
}
$new_array[] = $p[$i];
Will store $p[$i] into the next element of $new_array (a.k.a array_push()).
Have you thought about limiting your results in the sql query?
select * from image where img != '' limit 10
This way you are always given up to 10 results that are not empty.
A ẁhile loop might be what you're looking for http://php.net/manual/en/control-structures.while.php