How to get max element at each index while comparing two arrays? - php

I have two indexed arrays of identical length:
$first_array = [1,3,4,5,6];
$second_array = [5,2,1,7,9];
I need to generate a new array that consists of the higher value between the two elements at each index.
The output should be:
$output_array[5, 3, 4, 7, 9];

Super easy one-liner:
Pass both arrays to array_map(), as it synchronously loops through both sets of data, call max() on the two elements.
Code: (Demo)
$first_array = [1, 3, 4, 5, 6];
$second_array = [5, 2, 1, 7, 9];
var_export(array_map('max', $first_array, $second_array));
Output:
array (
0 => 5,
1 => 3,
2 => 4,
3 => 7,
4 => 9,
)

Try this way. demo
<?php
$first_array = array(1,3,4,5,6);
$second_array = array(5,2,1,7,9);
$return = array();
foreach($first_array as $key => $value){
if($first_array[$key] > $second_array[$key]){
$return[] = $first_array[$key];
}else{
$return[] = $second_array[$key];
}
}
print_r($return);

Related

How to remove unique elements within multidimensional array?

How to remove dulicate keys from multidimensional array?
My array is as follows:
$array = [[0, 1, 2, 3, 4], [1, 2, 3, 4, 6]];
My desired array should be:
$array = [[0, 1, 2, 3, 4], [6]];
Here's a quick and dirty solution for you:
Walk through every element of the array recursively and if you've not seen an element set it to null (unsetting it doesn't work for some reason). Then filter the resulting sub-arrays.
$array = [[0, 1, 2, 3, 4], [1, 2, 3, 4, 6]];
$seen = [];
array_walk_recursive($array, function (&$v) use (&$seen) {
if (!array_key_exists($v, $seen) {
$seen[$v] = true;
} else {
$v = null;
}
});
$final = array_map('array_filter', $array);
If the functions array_diff() and array_values​​() are used, the solution can be delivered in one line of code:
$array = [[0, 1, 2, 3, 4], [1, 2, 3, 4, 6]];
$array[1] = array_values(array_diff($array[1],$array[0]));
var_export($array);
Output:
array (
0 =>
array (
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
),
1 =>
array (
0 => 6,
),
)
$serialize=array_map('serialize',$array);
$unique=array_unique($serialize);
$result=array_map('unserialize',$uniue);
print_r($result);

Map an array of values to an array of each value's rank in the array

I have a array like this:
$row_arr_1=array(7,9,5,10);
now I want to get the result array like this:
$row_arr_2=array(3,2,4,1);
Explanation:
As 10 is the largest value in row_arr_1, then it will be replaced with value 1.
Similarly, as 9 is the 2nd highest value of row_arr_1, then it will be replaced by 2 and so on.
I tried to sort the values of row_arr_1 but the position is changed.
How
can i get my desired result?
It can be done using rsort() and array_search()
$row_arr_1=array(7,9,5,10);
$row_copy = $row_arr_1;
$row_arr_2 = array();
rsort($row_copy);
foreach($row_arr_1 as $val) {
$row_arr_2[] = array_search($val, $row_copy) + 1;
}
print_r($row_arr_2);
https://eval.in/990078
You can use arsort() to sort the array while preserving keys, and use those keys for your array via array_keys():
$row_arr_1 = array(7,9,5,10);
$row_arr_1_backup = $row_arr_1;
arsort($row_arr_1_backup);
$row_arr_2 = array_keys($row_arr_1_backup);
asort($row_arr_2);
$row_arr_2 = array_keys($row_arr_2);
array_walk($row_arr_2, function(&$item, &$key) {
$item = $item + 1;
});
You have to duplicate the original array, since arsort will sort the actual array it points to, rather than returning a new array.
$row_arr_1_old = array(7, 9, 5, 10);
$row_arr_1 = array(7, 9, 5, 10);
rsort($row_arr_1);
$test = [];
foreach ($row_arr_1_old as $key => $value) {
$test[] = array_search($value, $row_arr_1);
}
print_r($test);
For best efficiency try to reduce total function calls; this especially means minimizing / eliminating iterated function calls.
This is my slightly more efficient version of ahsan's answer.
Code: (Demo)
$copy = $arr = [7, 9, 5, 10];
rsort($arr); // generates: [10, 9, 7, 5]
$flipped = array_flip($arr); // generates: [10 => 0, 9 => 1, 7 => 2, 5 => 3]
foreach($copy as $v) {
$result[] = ++$flipped[$v]; // adds one to each accessed value from $flipped
}
var_export($result);
Output:
array (
0 => 3,
1 => 2,
2 => 4,
3 => 1,
)

PHP compare arrays

I have two arrays. $arrayOld and $arrayNew and I want to compare these arrays and only select the values that are not in $arrayNew.
I don't want the values that are in $arrayNew only. So I don't think array_diff() is gonna help me.
$arrayOld = [1, 2, 3, 4, 5]
$arrayNew = [1, 4, 5, 6, 7]
So it only needs to return 2 and 3 and not 6 or 7.
use array_diff, to accomplish this. As you need to difference between the array and need data from Old array so you need to use the old array as the first parameter of the array_diff.
Note: Array diff only returns from the first array which is not in second array.
$arrayOld = [1, 2, 3, 4, 5];
$arrayNew = [1, 4, 5, 6, 7];
$n = array_diff($arrayOld, $arrayNew);
print_r($n);
Result: Online Check
Array
(
[1] => 2
[2] => 3
)
If you need a new keys for the output array just use array_values. The new key start from 0.
$arr = array_values($n);
Use below code
$arrayOld = [1, 2, 3, 4, 5];
$arrayNew = [1, 4, 5, 6, 7];
print "<pre>";
print_r(array_diff($arrayOld, $arrayNew));
OUTPUT:
Array
(
[1] => 2
[2] => 3
)
use this code.
$arrayOld = array(1, 2, 3, 4, 5);
$arrayNew = array(1, 4, 5, 6, 7);
print_r(array_diff($arrayOld, $arrayNew));
$compare = array();
$i=1;
foreach($arrayOld as $k=>$v){
if(!in_array($v, $arrayNew)){
$compare[$i] = $v;
$i++;
}
}
$i=$i;
foreach($arrayNew as $k=>$v){
if(!in_array($v, $arrayOld)){
$compare[$i] = $v;
$i++;
}
}
use array_diff function
$arrayOld = array(1, 2, 3, 4, 5);
$arrayNew = array(1, 4, 5, 6, 7);
print_r(array_diff($arrayOld, $arrayNew));

Displaying number of instances of each array value

$myArray = array(2, 7, 4, 2, 5, 7, 6, 7);
$uniques = array_unique($myArray);
Along with displaying each value in the array only once, how would I ALSO display (in the foreach loop below) the number of times each value is populated in the array. IE next to '7' (the array value), I need to display '3' (the number of times 7 is in the array)
foreach ($uniques as $values) {
echo $values . " " /* need to display number of instances of this value right here */ ;
}
Use the array_count_values function instead.
$myArray = array(2, 7, 4, 2, 5, 7, 6, 7);
$values = array_count_values($myArray);
foreach($values as $value => $count){
echo "$value ($count)<br/>";
}
Have a look at array_count_values.
Quoting from the manual:
Example #1 array_count_values() example
<?php
$array = array(1, "hello", 1, "world", "hello");
print_r(array_count_values($array));
?>
The above example will output:
Array
(
[1] => 2
[hello] => 2
[world] => 1
)

Merge two flat arrays and omit values from one array when the other array has more occurrences of the same value

I want to merge every element of two arrays, BUT if a value is in both arrays, then only add the values from the array which has the biggest amount of that element. The result array does not need to be sorted in any special way, but I did it here for readability.
Sample input:
$array1 = [1, 4, 7, 3, 3, 3];
$array2 = [4, 0, 3, 4, 9, 9];
Desired result:
[0, 1, 3, 3, 3, 4, 4, 7, 9, 9]
//a2 a1 a1 a1 a1 a2 a2 a1 a2 a2
Note, this will be used on big arrays, with unknown integer values. Is there a good way to do this that doesn't require too much time/processing power?
Try this:
<?php
$array1 = [1, 4, 7, 3, 3, 3];
$array2 = [4, 0, 3, 4, 9, 9];
function min_merge($arr1, $arr2) {
$arr1 = array_count_values($arr1);
$arr2 = array_count_values($arr2);
foreach ($arr2 as $index => $arr)
if (!isset($arr1[$index]) || $arr > $arr1[$index])
$arr1[$index] = $arr;
foreach ($arr1 as $index => $arr)
for ($i = 0; $i < $arr; $i++)
$final[] = $index;
return $final;
}
print_r(min_merge($array1, $array2));
Output:
Array (
[0] => 1
[1] => 4
[2] => 4
[3] => 7
[4] => 3
[5] => 3
[6] => 3
[7] => 0
[8] => 9
[9] => 9
)
Unsorted, but it contains all the numbers from [0, 1, 3, 3, 3, 4, 4, 7, 9, 9].
$count[0] = array_count_values($arr1);
$count[1] = array_count_values($arr2);
$out = array();
array_map(function($e) use(&$out, $count){
$n1 = (isset($count[0][$e])) ? $count[0][$e] : 0;
$n2 = (isset($count[1][$e])) ? $count[1][$e] : 0;
$next = ($n2 > $n1) ? array_fill(0, $n2, $e) : array_fill(0, $n1, $e);
$out = array_merge($out, $next);
}, array_keys($count[0] + $count[1]));
print_r($out);
My modernized rewrite of #DaveChen's answer using PSR-12 coding standards and eliminating single-use declarations. This approach uses one loop to determine the greater count for numbers shared by both value-count arrays, then a second loop to populate the result array. (Demo)
$counts1 = array_count_values($array1);
foreach (array_count_values($array2) as $number => $count) {
if ($count > ($counts1[$number] ?? 0)) {
$counts1[$number] = $count;
}
}
$result = [];
foreach ($counts1 as $number => $count) {
array_push($result, ...array_fill(0, $count, $number));
}
var_export($result);
My modernized rewrite of #Expedito's answer which does not abuse the array_map() (when array_map()'s return value is not used, use array_walk() for functional style programming), uses a foreach() loop to eliminate variable scope issues, and generally implements D.R.Y. techniques. (Demo)
$counts1 = array_count_values($array1);
$counts2 = array_count_values($array2);
$result = [];
foreach ($counts1 + $counts2 as $num => $cnt) {
array_push(
$result,
...array_fill(
0,
max($counts1[$num] ?? 0, $counts2[$num] ?? 0),
$num
)
);
}
var_export($result);
And I wanted to add a new approach of my own, despite the fact that it may or may not perform better than the other two snippets. The script makes one pass over the first value count arrays to populate a temporary array which demands which numbers from the first array should be represented in the result array. Then it isolates value intersections from the first array, value differences from the second array, then merges them. (Demo)
$counts1 = array_count_values($array1);
$counts2 = array_count_values($array2);
$keepFrom1 = array_keys(
array_filter(
$counts1,
fn($count, $number) => ($counts2[$number] ?? 0) <= $count,
ARRAY_FILTER_USE_BOTH
)
);
var_export(
array_merge(
array_intersect($array1, $keepFrom1),
array_diff($array2, $keepFrom1)
)
);
probably not the most optimized but
<?php
$one=[1, 4, 7, 3, 3, 3];
$two=[4, 0, 3, 4, 9, 9];
sort($one);
sort($two);
foreach($one as $el)
{
$combined[]=$el;
if (array_search($el,$two))
{
unset($two[array_search($el,$two)]);
}
}
foreach($two as $el)
{
$combined[]=$el;
}
sort($combined);
print_r($combined);
?>

Categories