Using a regular for loop, it's possible to comapred the current index with the last to tell if I'm in the last iteration of the loop. Is there a similar thing when using foreach? I mean something like this.
foreach($array as $item){
//do stuff
//then check if we're in the last iteration of the loop
$last_iteration = islast(); //boolean true/false
}
If not, is there at least a way to know the current index of the current iteration like $iteration = 5, so I can manually compare it to the length of the $array?
The counter method is probably the easiest.
$i = count($array);
foreach($array as $item){
//do stuff
//then check if we're in the last iteration of the loop
$last_iteration = !(--$i); //boolean true/false
}
You can use a combination of SPL’s ArrayIterator and CachingIterator class to have a hasNext method:
$iter = new CachingIterator(new ArrayIterator($arr));
foreach ($iter as $value) {
$last_iteration = !$iter->hasNext();
}
Here are a few methods for this;
$items = ["Bhir", "Ekky", null, "Uych", "foo"=>"bar"];
$values = array_values($items);
// Bhir, Ekky, Uych, bar
foreach ($values as $i => $item) {
print("$item");
$next = isset($values[$i + 1]);
if ($next) {
print(", ");
}
}
// Bhir, Ekky, , Uych, bar
foreach ($values as $i => $item) {
print("$item");
$next = array_key_exists($i + 1, $values);
if ($next) {
print(", ");
}
}
// Bhir, Ekky, , Uych, bar
$i = count($values);
foreach ($items as $item) {
print("$item");
$next = !!(--$i);
if ($next) {
print(", ");
}
}
// Bhir, Ekky, , Uych, bar
$items = new \CachingIterator(new \ArrayIterator($items));
foreach ($items as $item) {
print("$item");
$next = $items->hasNext();
if ($next) {
print(", ");
}
}
No, you need to have a counter and know the amount of items in the list. You can use end() to get the last item in an array and see if it matches the current value in your foreach.
If you know that the values of the array will always be unique, you can compare the current $item to end($array) to know if you're at the last item yet. Otherwise, no, you need a counter.
You can get the key and the value in foreach() like this:
foreach($array as $key=>$value) { ... }
Alternatively, you could do a count() of the array so you know how many items there are and have an incrementing counter so that you know when you've reached the last item.
end($array);
$lastKey = key($array);
foreach($array as $key => $value) {
if ($key === $lastKey) {
// do something endish
}
}
The valid() method says if the ArrayIterator object has more elements.
See:
$arr = array("Banana","Abacaxi","Abacate","Morango");
$iter = new ArrayIterator($arr);
while($iter->valid()){
echo $iter->key()." - ".$iter->current()."<br/>";
$iter->next();
}
Related
I have a foreach loop, in which I loop through the array. I want to add elements as I go through it and have new ones go through it as well.
Now with this code it only does the iterations that I have in the array at the beginning (1 in this case).
Can somebody help me
Thanks
public static function getDirectoriesChilds($id_parent, $parents_array) {
$session_client = Client::getSessionClient();
array_push($parents_array, $id_parent);
$parents_array = array_unique($parents_array);
foreach ($parents_array as $element) {
$childs = Directory::where('id_parent' , '=', $element)->get();
foreach ($childs as $child) {
if ($child->deleted == Controller::DISABLED) {
array_push($parents_array, $child->id);
$parents_array = array_unique($parents_array);
}
}
}
return $parents_array;
}
If changes foreach to for works.
for($i=0; $i<count($parents_array); $i++){
Using below array, i'm trying to use foreach loop to iterate through each item. Then i need to apply if condition to check if the given number is even and odd. I also need to create two arrays one for even and one for odd and push each number in their respective category.
So i have done this so far:
These are the two arrays i created to push through the values to.
}
$numbers = [1,2,3,4,5,6,7,8,9,10,11,12,13,14];
$array_odd = [];
$array_even = [];
foreach ($numbers as $value)
{
if (value %2 == 0)
{
$array_even = $value;
echo $array_even;
}
else
{
$array_odd = $value;
echo $array_odd;
}
I'd like to know if i'm using the correct solution or are there major errors im committing?
It will surely work like charms.
$numbers = [1,2,3,4,5,6,7,8,9,10,11,12,13,14];
$array_odd = [];
$array_even = [];
foreach ($numbers as $value)
{
if ($value %2 == 0)
{
$array_even[] = $value;
}
else
{
$array_odd[] = $value;
}
}
echo "<pre>";
print_r($array_odd);
echo "<pre>";
print_r($array_even);
I have a loop that needs to go through each item. So naturally a foreach loop seems like the best idea. However, I need to add an element to the array as it iterates. I tried the following without any luck.
foreach ($allitems as $item) {
//Do some stuff here
if ($value === true)
$allitems[] = 'New item';
}
I found out the foreach loops seem to use a referenced copy of the array, so editing the array does not register in the loop.
A workaround is to use the older styled while loops as follows:
while (list($key, $item) = each($allitems)) {
//Do some stuff here
if ($value === true)
$allitems[] = 'New item';
}
Clearly a foreach loop would be nicer and more efficient. Is it possible? Or is the while structure the best possible solution.
Yeah, it is possible:
foreach ($allitems as &$item) {
//Do some stuff here
if ($value === true)
$allitems[] = 'New item';
}
According to the docs, you need to pass a reference (using the & in front if $item)
More concrete example:
<?php
$allitems = array(1,2,3,4);
foreach ($allitems as &$item) {
echo $item."\n";
if ($item == 2) {
$allitems[] = "Blah";
}
}
?>
This outputs (using php from commandline)
1
2
3
4
Blah
It seems like an ordinary for loop would be best for this:
for ($i = 0; $i < count($array); $i++) {
// Do some stuff here that calculates $value from $array[$i]
if ($value === true) {
$array[] = "New Element";
}
}
You could do foreach...like this....
But it adds more code...so its not any better than your while loop..
foreach($array as $val){
if($val=="check"){$append[]="New Item";}
}
$array = array_merge($array, $append);
Of course, if you want your structure maintained..then rather use array_push
I need to combine two different data types, an array and an array object.
I then need to display them on a page in order of a certain attribute (date).
The markup for access is similar to the following:
foreach($array as $item){
$item['date'];
}
and
foreach($object as $item){
$item->post->date
}
is array_merge what I need, or something different?
Not that if possible I'd like to do this on the fly, as data will be changing rapidly and there is no need for storage.
Thanks!
Here's how I would do it:
// array we will use for sorting
$finalArray = array();
// add the array's using the date as the key
foreach($array as $item){
$key = $item['date']; // use date here, example $key = date('l \t\h\e jS',$item['date']);
$finalArray[$key] = $item;
}
// add the objects's using the date as the key
foreach($object as $item){
$finalArray[$item->post->date] = $item;
}
//now sort by keys as Xeoncross noted
ksort($finalArray);
foreach($finalArray as $date=>$objOrArray){
if(is_array($objOrArray)){
//do your array printing here
} else {
//do your object printing here
}
}
Ofcourse we can turn the object into an array with get_object_vars, and use whatever sorting function on the final array, the important part is that we want to sort by date and that's why we need it to be our key.
Hope that helped.
foreach($array as $item){
$array_new[] = $item['date'];
}
foreach($object as $item){
$array_new[] = $item->post->date;
}
sort($array_new);
$dates = array();
foreach ($array as $item) {
$dates[] = $item['date'];
}
foreach ($object as $item) {
$dates[] = $item->post->date;
}
sort($dates);
foreach ($dates as $date) {
echo $date;
}
You could try this if you need multiple values from the objects (not just date) and you don't mind duplicates being erased.
// $array is already defined right?
$object = json_decode(json_encode($object), TRUE);
$data = array_merge($array, $object);
print_r($data); // now test it
http://us2.php.net/array_merge
http://us3.php.net/json_decode (note the second TRUE param)
Edit
Based on Perfection's answer, (and re-reading the question) I would do this:
$finalArray = array();
foreach($array as $item)
{
$finalArray[$item['date']] = $item;
}
foreach($object as $item)
{
$finalArray[$item->post->date] = json_decode(json_encode($item), TRUE);
}
ksort($finalArray);
foreach($finalArray as $date => $item)
{
// Everything is an array now
}
How to calculate how many items in a foreach?
I want to count total rows.
foreach ($Contents as $item) {
$item[number];// if there are 15 $item[number] in this foreach, I want get the value : 15
}
If you just want to find out the number of elements in an array, use count. Now, to answer your question...
How to calculate how many items in a foreach?
$i = 0;
foreach ($Contents as $item) {
$item[number];// if there are 15 $item[number] in this foreach, I want get the value : 15
$i++;
}
If you only need the index inside the loop, you could use
foreach($Contents as $index=>$item) {
// $index goes from 0 up to count($Contents) - 1
// $item iterates over the elements
}
You don't need to do it in the foreach.
Just use count($Contents).
count($Contents);
or
sizeof($Contents);
foreach ($Contents as $index=>$item) {
$item[$index];// if there are 15 $item[number] in this foreach, I want get the value : 15
}
There's a few different ways you can tackle this one.
You can set a counter before the foreach() and then just iterate through which is the easiest approach.
$counter = 0;
foreach ($Contents as $item) {
$counter++;
$item[number];// if there are 15 $item[number] in this foreach, I want get the value : 15
}
Try:
$counter = 0;
foreach ($Contents as $item) {
something
your code ...
$counter++;
}
$total_count=$counter-1;
$Contents = array(
array('number'=>1),
array('number'=>2),
array('number'=>4),
array('number'=>4),
array('number'=>4),
array('number'=>5)
);
$counts = array();
foreach ($Contents as $item) {
if (!isset($counts[$item['number']])) {
$counts[$item['number']] = 0;
}
$counts[$item['number']]++;
}
echo $counts[4]; // output 3
foreach ($array as $value)
{
if(!isset($counter))
{
$counter = 0;
}
$counter++;
}
//Sorry if the code isn't shown correctly. :P
//I like this version more, because the counter variable is IN the foreach, and not above.
You can do sizeof($Contents) or count($Contents)
also this
$count = 0;
foreach($Contents as $items) {
$count++;
$items[number];
}
Imagine a counter with an initial value of 0.
For every loop, increment the counter value by 1 using $counter = 0;
The final counter value returned by the loop will be the number of iterations of your for loop. Find the code below:
$counter = 0;
foreach ($Contents as $item) {
$counter++;
$item[number];// if there are 15 $item[number] in this foreach, I want get the value `: 15`
}
Try that.
$index = 0;
foreach( $array ?? [] as $index=> $item ) {
$index++;
$data[] = array(
'id' =>$index
);
}