PHP Pass multiple values to a foreach function - php

I am wondering how in PHP would I pass multiple arrays to a for each loop.
For example, in the following I'd want to pass both $array1 and $array2 to this for each loop, rather than have the for each loop written twice.
$array1 = somestring;
$array2 = someotherstring;
foreach ($array1 as $vals) {
//do something cool
}
Edit: To clarify, I am aware that the array declarations are not valid. It is just a placeholder. That does not deserve a downvote. I want to run the entire foreach loop with $array1, and then run it again with $array2.

$array3 = array_merge($array1, $array2);
foreach ($array3 as $vals) {
// do your coolness
}

You can kind of zip two indexed arrays with array_map(null, $array1, $array2). This way you will have a list of tuples, where the first element will be from $array1 and the second - from $array2. You can iterate over this list and access both arrays elements in one iteration.
$array1 = [1, 2, 3];
$array2 = [1, 2, 3];
$zip = array_map(null, $array1, $array2);
foreach ($zip as $tuple) {
echo $tuple[0], '-', $tuple[1], PHP_EOL;
}
Here is demo.
Be aware that your arrays (in this case lists) have to be the same length. Other wise you will end up with broken tuples, one elements of which will be null.

Related

Remove only one matching element from two arrays

$array1 = array(1.99);
$array2 = array(1.99, 1.99, 2.99);
I want to remove only one matching element of $array1, from $array2.
so, What I want is:
1.99
2.99
Ive tried array_diff(), which will take out both of the 1.99 and leave me with only 2.99.
You can take advantage of the fact array_search will only return one matching element from the target array, and use it to remove that from $array2:
$array1 = array(1.99);
$array2 = array(1.99, 1.99, 2.99);
foreach ($array1 as $remove) {
unset($array2[array_search($remove, $array2)]);
}
If $array1 can contain elements that aren't present in $array2 then you'll need to add a check that the result of array_search is not false.
First merge the two arrays the find unique elements .Try array_merge() and array_unique()
<?php
$array1 = array(1.99);
$array2 = array(1.99, 1.99, 2.99);
print_r(array_unique(array_merge($array1, $array2)));
?>
I did similar to #iainn:
foreach($array1 as $k=>$v){
if(in_array($v, $array2)){
unset($array1[$k]);
break;
}
}

How can I remove the current element in a foreach loop from the array, without changing the original array?

How can I get a new array with all elements except the current element passed into the foreach loop. See example below:
$numbers = [1, 2, 3, 4, 5];
foreach($numbers as $numer){
// Get a new array with 4 elements excluding the $numer
// For example for first loop I want a array [2, 3, 4, 5]
}
I tried doing:
foreach($numbers as $i=>$numer) {
unset($numbers[$i]);
echo '<pre>';
var_dump($numbers);
echo '</pre>';
}
It works but it alters original array. Is there any PHP function to get new array without affecting original one?
$numbers = array(1,2,3,4,5);
if (($key = array_search($numer, $numbers)) !== false) {
unset($numbers[$key]);
}
If you want to delete all instances of $numer, simply replace if with while.
Edit: I see you've changed your question to include not changing the original array. You can copy the array and manipulate the copied array in that case.
This should work for you:
Just use array_diff_key() to get the entire array, expect the current element, e.g.
<?php
$numbers = [1, 2, 3, 4, 5];
foreach($numbers as $key => $numer){
print_r(array_diff_key($numbers, array_flip([$key])));
}
?>
EDIT:
If you don't have the key, you can simply use array_keys() to get all keys, e.g.
$numbers = [1, 2, 3, 4, 5];
$value = 32;
print_r(array_diff_key($numbers, array_flip(array_keys($numbers, $value))));
This will work
<?php
$numbers = array(1,2,3);
foreach($numbers as $index => $value){
$temp = $numbers;
unset($temp[$index]);
$new_array = $temp;
echo '<pre>'.print_r($new_array, true).'</pre>';
}
?>

Using PHP remove duplicates from an array without using any in- built functions?

Lets say I have an array as follows :
$sampArray = array (1,4,2,1,6,4,9,7,2,9)
I want to remove all the duplicates from this array, so the result should be as follows:
$resultArray = array(1,4,2,6,9,7)
But here is the catch!!! I don't want to use any PHP in built functions like array_unique().
How would you do it ? :)
Here is a simple O(n)-time solution:
$uniqueme = array();
foreach ($array as $key => $value) {
$uniqueme[$value] = $key;
}
$final = array();
foreach ($uniqueme as $key => $value) {
$final[] = $key;
}
You cannot have duplicate keys, and this will retain the order.
A serious (working) answer:
$inputArray = array(1, 4, 2, 1, 6, 4, 9, 7, 2, 9);
$outputArray = array();
foreach($inputArray as $inputArrayItem) {
foreach($outputArray as $outputArrayItem) {
if($inputArrayItem == $outputArrayItem) {
continue 2;
}
}
$outputArray[] = $inputArrayItem;
}
print_r($outputArray);
This depends on the operations you have available.
If all you have to detect duplicates is a function that takes two elements and tells if they are equal (one example will be the == operation in PHP), then you must compare every new element with all the non-duplicates you have found before. The solution will be quadratic, in the worst case (there are no duplicates), you need to do (1/2)(n*(n+1)) comparisons.
If your arrays can have any kind of value, this is more or less the only solution available (see below).
If you have a total order for your values, you can sort the array (n*log(n)) and then eliminate consecutive duplicates (linear). Note that you cannot use the <, >, etc. operators from PHP, they do not introduce a total order. Unfortunately, array_unique does this, and it can fail because of that.
If you have a hash function that you can apply to your values, than you can do it in average linear time with a hash table (which is the data structure behind an array). See
tandu's answer.
Edit2: The versions below use a hashmap to determine if a value already exists. In case this is not possible, here is another variant that safely works with all PHP values and does a strict comparison (Demo):
$array = array (1,4,2,1,6,4,9,7,2,9);
$unique = function($a)
{
$u = array();
foreach($a as $v)
{
foreach($u as $vu)
if ($vu===$v) continue 2
;
$u[] = $v;
}
return $u;
};
var_dump($unique($array)); # array(1,4,2,6,9,7)
Edit: Same version as below, but w/o build in functions, only language constructs (Demo):
$array = array (1,4,2,1,6,4,9,7,2,9);
$unique = array();
foreach($array as $v)
isset($k[$v]) || ($k[$v]=1) && $unique[] = $v;
var_dump($unique); # array(1,4,2,6,9,7)
And in case you don't want to have the temporary arrays spread around, here is a variant with an anonymous function:
$array = array (1,4,2,1,6,4,9,7,2,9);
$unique = function($a) /* similar as above but more expressive ... ... you have been warned: */ {for($v=reset($a);$v&&(isset($k[$v])||($k[$v]=1)&&$u[]=$v);$v=next($a));return$u;};
var_dump($unique($array)); # array(1,4,2,6,9,7)
First was reading that you don't want to use array_unique or similar functions (array_intersect etc.), so this was just a start, maybe it's still of som use:
You can use array_flip PHP Manual in combination with array_keys PHP Manual for your array of integers (Demo):
$array = array (1,4,2,1,6,4,9,7,2,9);
$array = array_keys(array_flip($array));
var_dump($array); # array(1,4,2,6,9,7)
As keys can only exist once in a PHP array and array_flip retains the order, you will get your result. As those are build in functions it's pretty fast and there is not much to iterate over to get the job done.
<?php
$inputArray = array(1, 4, 2, 1, 6, 4, 9, 7, 2, 9);
$outputArray = array();
foreach ($inputArray as $val){
if(!in_array($val,$outputArray)){
$outputArray[] = $val;
}
}
print_r($outputArray);
You could use an intermediate array into which you add each item in turn. prior to adding the item you could check if it already exists by looping through the new array.

How to Combine two arrays randomly in PHP

How to combine two arrays into single one and i am requesting this in such a way that the 3rd combination array should contains one value from one array and the next one from other array and so on.. or ( it could be random)
ex:
$arr1 = (1, 2, 3, 4, 5);
$arr2 = (10, 20, 30, 40, 50);
and combined array
$arr3 = (1, 10, 2, 20, 3, 30, ...);
If it can be random, this will solve your problem:
$merged = array_merge($arr1, $arr2);
shuffle($merged);
I also made a function for fun that will produce the exact output you had in your question. It will work regardless of the size of the two arrays.
function FosMerge($arr1, $arr2) {
$res=array();
$arr1=array_reverse($arr1);
$arr2=array_reverse($arr2);
foreach ($arr1 as $a1) {
if (count($arr1)==0) {
break;
}
array_push($res, array_pop($arr1));
if (count($arr2)!=0) {
array_push($res, array_pop($arr2));
}
}
return array_merge($res, $arr2);
}
This will return a random array:
$merged = array_merge($arr1,$arr2);
shuffle($merged);
sort($arr3 = array_merge($arr1, $arr2));
array_merge() will merge your arrays into one. sort() will sort the combined array.
If you want it random instead of sorted:
shuffle($arr3 = array_merge($arr1, $arr2));
$arr3 contains the array you're looking for.
You can use
<?php
arr3 = array_merge ($arr1 , $arr2 );
print_r(arr3);
?>
which will output in
$arr3 = (1,2,3,4,5,10,20,30,40,50)

How can I use in_array if the needle is an array?

I have 2 arrays, the value will be loaded from database, below is an example:
$arr1 = array(1,2,3);
$arr2 = array(1,2,3,4,5,6,7);
What I want to do is to check if all the values in $arr1 exist in $arr2. The above example should be a TRUE while:
$arr3 = array(1,2,4,5,6,7);
comparing $arr1 with $arr3 will return a FALSE.
Normally I use in_array because I only need to check single value into an array. But in this case, in_array cannot be used. I'd like to see if there is a simple way to do the checking with a minimum looping.
UPDATE for clarification.
First array will be a set that contains unique values. Second array can contain duplicated values. They are both guaranteed an array before processing.
Use array_diff():
$arr1 = array(1,2,3);
$arr2 = array(1,2,3,4,5,6,7);
$arr3 = array_diff($arr1, $arr2);
if (count($arr3) == 0) {
// all of $arr1 is in $arr2
}
You can use array_intersect or array_diff:
$arr1 = array(1,2,3);
$arr2 = array(1,2,3,4,5,6,7);
if ( $arr1 == array_intersect($arr1, $arr2) ) {
// All elements of arr1 are in arr2
}
However, if you don't need to use the result of the intersection (which seems to be your case), it is more space and time efficient to use array_diff:
$arr1 = array(1,2,3);
$arr2 = array(1,2,3,4,5,6,7);
$diff = array_diff($arr1, $arr2);
if ( empty($diff) ) {
// All elements of arr1 are in arr2
}
You can try use the array_diff() function to find the difference between the two arrays, this might help you. I think to clarify you mean, all the values in the first array must be in the second array, but not the other way around.
In my particular case I needed to check if a pair of ids was processed before or not. So simple array_diff() did not work for me.
Instead I generated keys from ids sorted alphabetically and used them with in_array:
<?php
$pairs = array();
// ...
$pair = array($currentId, $id);
sort($pair);
$pair = implode('-', $pair);
if (in_array($pair, $pairs)) {
continue;
}
$pairs[$pair] = $pair;
This is probably not an optimum solution at all but I just needed it for a dirty script to be executed once.

Categories