How to Count Skipped Items in PHP array - php

lets suppose that I have an Array;
$array = [1, 2, "Mohcin", "Mohammed", 3,];
I can Access this array and skip the items "Mohcin" and "Mohammed" inside the iteration using for or foreach loop and continue.. but my question how I can count the number of items that I skipped inside the loop? and that is "TWO" in this case.
Thanks in advance

$array = [1, 2, "Mohcin", "Mohammed", 3,];
$skipped = 0;
foreach ($array as $element) {
if ($someCondition) {
// Remove the element
$skipped++;
}
}
// You access $skipped here

You can do it even without a foreach loop.
$array = [1, 2, "Mohcin", "Mohammed", 3,];
$skip = ["Mohcin", "Mohammed"];
$diff = array_diff($array, $skip);
$skipCount = count($array) - count($diff);
echo $skipCount; // prints 2
But if you want with foreach for the reason of more complex logic, do like this
$skipCount = 0;
foreach($array as $value) {
if($value === "Mohcin" || $value === "Mohammed") {
$skipCount++;
continue;
}
// Do anything else when not skipped
}
echo $skipCount; // prints 2

You need to create variable that keeps count of skips every time you skip value.
$skips = 0;
for($counter = 0; $counter < count($array); $counter++) {
if(skip) {
$skips++;
continue;
}
}

Related

Checking the equality of all values in array in php

I check the equality of all values in the array in php this way. I could not find how to do this on any web page, if there is an easier method you can write.
$array = array(2, 2, 1);
$first_value = $array[0];
$count_invoice = count($array);
$i = 0;
foreach ($array as $item) {
if ($item == $first_value) {
$i++;
} else {
// Not equal.
}
}
if ($i == $count_invoice) {
echo "Array equal.";
} else {
echo "Array not equal.";
}
There's no need to count anything. As soon as you see the value, which not equals $first_value, you can break the loop:
$array = array(2, 2, 2);
$first_value = array_shift($array);
$allEquals = true;
foreach ($array as $item) {
if ($item != $first_value) {
$allEquals = false;
break;
}
}
if ($allEquals) {
echo "Array equal.";
} else {
echo "Array not equal.";
}
Good job on finding a solution yourself. However, your code is a little convoluted and might be simplified. I understand you don't have an actual question, but you may find my suggested improvement useful anyway.
<?php
// Your input array.
$array = array(2, 1, 1);
// Another array, which consists of unique elements.
$uniqueArray = array(1, 1, 1);
// Use array_unique() to remove duplicates, and count the results. If there is more than one value, then the array didn't consist of all unique values.
var_dump(count(array_unique($array)) === 1); // FALSE
var_dump(count(array_unique($uniqueArray)) === 1); // TRUE

Find first duplicate in an array

Given an array a that contains only numbers in the range from 1 to a.length, find the first duplicate number for which the second occurrence has the minimal index. In other words, if there are more than 1 duplicated numbers, return the number for which the second occurrence has a smaller index than the second occurrence of the other number does. If there are no such elements, return -1.
My code:
function firstDuplicate($a) {
$unique = array_unique($a);
foreach ($a as $key => $val) {
if ($unique[$key] !== $val){
return $key;
}else{
return -1;
}
}
}
The code above will be OK when the input is [2, 4, 3, 5, 1] but if the input is [2, 1, 3, 5, 3, 2] the output is wrong. The second duplicate occurrence has a smaller index. The expected output should be 3.
How can I fix my code to output the correct result?
$arr = array(2,1,3,5,3,2);
function firstDuplicate($a) {
$res = -1;
for ($i = count($a); $i >= 1; --$i) {
for ($j = 0; $j < $i; ++$j) {
if ($a[$j] === $a[$i]) {
$res = $a[$j];
}
}
}
return $res;
}
var_dump(firstDuplicate($arr));
By traversing the array backwards, you will overwrite any previous duplicates with the new, lower-indexed one.
Note: this returns the value (not index), unless no duplicate is found. In that case, it returns -1.
// Return index of first found duplicate value in array
function firstDuplicate($a) {
$c_array = array_count_values($a);
foreach($c_array as $value=>$times)
{
if($times>1)
{
return array_search($value, $array);
}
}
return -1;
}
array_count_values() will count the duplicate values in the array for you then you just iterate over that until you find the first result with more then 1 and search for the first key in the original array matching that value.
Python3 Solution:
def firstDuplicate(a):
mySet = set()
for i in range(len(a)):
if a[i] in mySet:
return a[i]
else:
mySet.add(a[i])
return -1
function firstDuplicate($a) {
foreach($a as $index => $value) {
$detector[] = $value;
$counter = 0;
foreach($detector as $item) {
if($item == $value) {
$counter++;
if($counter >= 2) {
return $value;
break;
}
}
}
}
return -1;
}
It's easy to just get the first number that will be checked as duplicated, but unfortunately, this function exceeded 4 seconds with a large array of data, so please using it with a small scale of array data.
EDIT
I have new own code fixes execution time for large array data
function firstDuplicate($a) {
$b = [];
$counts = array_count_values($a);
foreach($counts as $num => $duplication) {
if($duplication > 1) {
$b[] = $num;
}
}
foreach($a as $value) {
if(in_array($value, $b)) {
$detector[] = $value;
$counter = 0;
foreach($detector as $item) {
if($item == $value) {
$counter++;
if($counter >= 2) {
return $value;
break;
}
}
}
}
}
return -1;
}
The new code target the current numbers having a reputation only by using array_count_values()
function firstDuplicate($a) {
$indexNumber = -1;
for($i = count($a); $i >= 1 ; --$i){
for($k = 0; $k < $i; $k++){
if(isset($a[$i]) && ($a[$i] === $a[$k]) ){
$indexNumber = $a[$k];
}
}
}
return $indexNumber;
}
Remove error from undefined index array.

php - print even and (sorted) odd numbers of an array

I have an array given below
$array = array(50,51,52,53,54,55,56,57,58,59);
I am trying to print the values of array while even numbers will remain in same order and the odd numbers are sorted i.e. 59,57,55,53,51
The output should be like
50,59,52,57,54,55,56,53,58,51
I've separated the even and odd numbers in two diff variables. how should i proceed further ?
here is my code
$even= "";
$odd= "";
for($i=50;$i<=59;$i++)
{
if($i%2==0)
{
$even.=$i.",";
}else $odd.=$i.",";
}
echo $even.$odd;
Instead of pushing the evens and odds into a string, push them each into an array, sort the array with the odds in reverse and then loop through one of them (preferably through the even array) and add the even and the odd to a new array.
This is how I've done it:
$array = array(50,51,52,53,54,55,56,57,58,59);
$odds = array();
$even = array();
foreach($array as $val) {
if($val % 2 == 0) {
$even[] = $val;
} else {
$odds[] = $val;
}
}
sort($even);
rsort($odds);
$array = array();
foreach($even as $key => $val) {
$array[] = $val;
if(isset($odds[$key])) {
$array[] = $odds[$key];
}
}
https://3v4l.org/2hW6T
But you should be cautious if you have less even than odd numbers, as the loop will finish before all odds are added. You can check for that either before or after you've filled the new array. If you check after filling the new array, you can use array_diff and array_merge to add the missing odds to the new array.
http://php.net/array_diff http://php.net/array_merge
Following code will run as per the odd number count. There won't be any loop count issue.
function oddNumber($num){
return $num % 2 == 1;
}
$givenArray = array(50, 51, 52, 53, 54, 55, 56, 57, 58, 59);
$oddArray = array_filter($givenArray, "oddNumber");
rsort($oddArray);
$finalArray = array();
$oddCount = 0;
foreach($givenArray as $num){
if(oddNumber($num)){
$finalArray[] = $oddArray[$oddCount];
++$oddCount;
}else{
$finalArray[] = $num;
}
}
print_r($finalArray);

php array sorting with next value difference

can anyone help me with this following Array sorting
Input
$array=array(1,2,3,6,7,8,100,101,200);
Output:
$new_array=array(
0=>array(1,2,3),
1=>array(6,7,8),
2=>array(100,101),
3=>array(200)
);
Thanks in advance!
$array=array(1,2,3,6,7,8,100,101,200);
$new_array = array();
$lastNumber = '';
foreach($array as $number) {
if($lastNumber === '') {
$otherArray = array($number);
}
elseif($lastNumber + 1 !== $number) {
$new_array[] = $otherArray;
$otherArray = array($number);
}
else{
$otherArray[] = $number;
}
$lastNumber = $number;
}
$new_array[] = $otherArray;
print_r($new_array);
You can loop over the array and check the distance to the next element in the array. If this distance is larger then one add a new sub array:
$array=array(1,2,3,6,7,8,100,101,200);
$result=array(array());
for($i=0; $i<count($array)-1; $i++)
{
if($array[$i+1]-$array[$i]==1)
{
// If difference to next number is one -> push
array_push($result[count($result)-1], $array[$i]);
}
else
{
// ... else: Push and create new array for the next element
array_push($result[count($result)-1], $array[$i]);
array_push($result, array());
}
}
// Push the last number
array_push($result[count($result)-1], $array[$i]);
print_r($result);
Just a different approach with array_push()...
Pretty simple: loop through the numbers, remember the last one, if the current number is not the successor of the last one, add a new array to your result, push into the last array in your result.
$result = [];
$last = null;
foreach ($array as $number) {
if ($last !== $number - 1) {
$result[] = [];
}
$result[count($result) - 1][] = $number;
$last = $number;
}
You could even get rid of $last and directly read the last array element of the last array element of $result, but that would make the code actually more complicated.

Continuously looping through an array

I'm trying to work out how to continuously loop through an array, but apparently using foreach doesn't work as it works on a copy of the array or something along those lines.
I tried:
$amount = count($stuff);
$last_key = $amount - 1;
foreach ($stuff as $key => $val) {
// Do stuff
if ($key == $last_key) {
// Reset array cursor so we can loop through it again...
reset($stuff);
}
}
But obviously that didn't work. What are my choices here?
An easy way is to combine an ArrayIterator with an InfiniteIterator.
$infinite = new InfiniteIterator(new ArrayIterator($array));
foreach ($infinite as $key => $val) {
// ...
}
You can accomplish this with a while loop:
while (list($key, $value) = each($stuff)) {
// code
if ($key == $last_key) {
reset($stuff);
}
}
This loop will never stop:
while(true) {
// do something
}
If necessary, you can break your loop like this:
while(true) {
// do something
if($arbitraryBreakCondition === true) {
break;
}
}
Here's one using reset() and next():
$total_count = 12;
$items = array(1, 2, 3, 4);
$value = reset($items);
echo $value;
for ($j = 1; $j < $total_count; $j++) {
$value = ($next = next($items)) ? $next : reset($items);
echo ", $value";
};
Output:
1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4
I was rather surprised to find no such native function. This is a building block for a Cartesian product.
You could use a for loop and just set a condition that's always going to be true - for example:
$amount = count($stuff);
$last_key = $amount - 1;
for($key=0;1;$key++)
{
// Do stuff
echo $stuff[$key];
if ($key == $last_key) {
// Reset array cursor so we can loop through it again...
$key= -1;
}
}
Obviously, as other's have pointed out - make sure you've got something to stop the looping before you run that!
Using a function and return false in a while loop:
function stuff($stuff){
$amount = count($stuff);
$last_key = $amount - 1;
foreach ($stuff as $key => $val) {
// Do stuff
if ($key == $last_key) {
// Reset array cursor so we can loop through it again...
return false;
}
}
}
while(stuff($stuff)===FALSE){
//say hello
}

Categories