Compare two associative arrays regarding the order of keys - php

Suppose, we have 2 associative arrays:
<?php
$array1 = array(
1 => 2,
2 => 1,
);
$array2 = array(
2 => 1,
1 => 2,
);
They contain same elements, but in different order. I wanted to write a comparison function, that will give true only if:
Arrays have the same key => value pairs.
Order of pairs is the same.
So, I tried the following:
1 try
if ($array1 == $array2)
{
print "equal\n";
}
Prints: equal
2 try
print count(array_diff_assoc($array1, $array1));
Prints: 0
My custom function
Then I created the following function:
function compare(&$array1, &$array2)
{
$n1 = count($array1);
$n2 = count($array2);
if ($n1 == $n2)
{
$keys1 = array_keys($array1);
$keys2 = array_keys($array2);
for ($i = 0; $i < $n1; ++$i)
{
if ($keys1[$i] == $keys2[$i])
{
if ($array1[$keys1[$i]] != $array2[$keys2[$i]])
{
return false;
}
}
else
{
return false;
}
}
return true;
}
else
{
return false;
}
}
This works correctly, but it won't work, when we want this strict comparison applied for nested arrays of arrays because of != operator in this if:
if ($array1[$keys1[$i]] != $array2[$keys2[$i]])
{
return false;
}
This can be fixed, using a recursive function, switching by type of data. But this simplified version was ok for me.
Is there any standard solution for this type of comparison?

As described under array operators, what you want is the === equality operator.
if ($array1 === $array2) {
echo "same key pairs and same element order\n";
}

can you try the this below one. which returns true
if the key=>value and will be in any order
otherwise returns false
$array1 = array(
1 => 2,
2 => 1);
$array2 = array(
2 => 1,
1 => 2);
var_dump(compareArray($array1,$array2));
function compareArray ($array1, $array2)
{
foreach ($array1 as $key => $value)
{
if ($array2[$key] != $value)
{
return false;
}
}
return true;
}

Related

Array comparison and re-order in PHP

Let's say I Have two arrays.
$arr1 = ['A','B','C','D'];
$arr2 = ['C','D'];
now compare two arrays.if there is no match for value of $arr1 in $arr2 then index is left empty.
for the above arrays output should be:
$arr3 = ['','','C','D']
I tried array_search() function.But couldn't achieve desired output.
Any possible solutions?
You can use foreach with in_array and array_push like:
$arr1 = ['A','B','C','D'];
$arr2 = ['C','D'];
$arr3 = [];
foreach($arr1 as $value){
$arr3[] = (in_array($value, $arr2)) ? $value : '';
}
print_r($arr3);
/*
Result
Array
(
[0] =>
[1] =>
[2] => C
[3] => D
) */
Foreach the first array then test with in_array if exist, if true push into array 3 else push empty value
You can use the following function. In the following code, the function search_in_array return true and false based on the searching within the 2nd array. So you can push the empty or searched value in final array.
<?php
$arr1 = array('A','B','C','D');
$arr2 = array('C','D');
$arr3 = array();
function search_in_array ($value, $array)
{
for ($i=0; $i<count($array); $i++)
{
if ($value == $array[$i])
{
return true;
}
}
return false;
}
for ($i=0; $i<count($arr1); $i++)
{
$value = $arr1[$i];
$result = search_in_array ($value, $arr2);
if ($result)
{
array_push ($arr3, $value);
}
else
{
array_push ($arr3, '');
}
}
print_array($arr3);
?>

why does array_intersect_uassoc() compare array keys within the same array?

Here's an example of using array_intersect_uassoc().
I've deliberately made the keys different, so you can tell which one comes from which array.
$array1 = array("LEFT a" => "green", "LEFT b" => "brown", "LEFT c" => "blue");
$array2 = array("RIGHT a" => "GREEN", "RIGHT B" => "brown", 'RIGHT y' => "yellow");
array_intersect_uassoc($array1, $array2, function($a, $b) {
print_r("$a -- $b");
return 0;
});
In the output, I see comparisons of two LEFT keys as well as two RIGHT keys.
What on earth is the point of doing this?
Looking at the logic code for the function (I simplified it a bit):
function array_intersect_uassoc($args, compare_func)
{
$result = array();
$array_count = count($args);
foreach ($args[0] as $k => $v) {
for ($i = 0; $i < $array_count; $i++) {
$match = false;
foreach ($args[$i] as $kk => $vv) {
$compare = call_user_func_array($compare_func, array($k, $kk));
if ($compare === 0 && $v == $vv) {
$match = true;
continue 2;
}
}
if ($match === false) {
continue 2;
}
}
if ($match === true) {
$result[$k] = $v;
}
}
return $result;
}
This helps you see that the keys are not the only thing checked, but more importantly the values as well.

Unsort in array

Good day.
I would be like get 3 keys from $arr where value $arN[0] will be more than other...
Code:
$ar1=array(201,281);
$ar2=array(1252760,1359724);
$ar3=array(452760,34349724);
$ar4=array(1260,134344);
$ar5=array(232750,1359724);
$ar6=array(60,1439724);
$arr[]=array(6299927 => $ar1);
$arr[]=array(1252760 => $ar2);
$arr[]=array(3432444 => $ar3);
$arr[]=array(3435543 => $ar4);
$arr[]=array(7645466 => $ar5);
$arr[]=array(4574534 => $ar6);
Next function sorting array $a descending:
function cmp($a, $b)
{
if ($a == $b) {
return 0;
}
return ($a < $b) ? 1 : -1;
}
$a = array(3, 2, 5, 6, 1);
usort($, "cmp");
foreach ($a as $key => $value) {
echo "$key: $value\n";
}
outpoot: 0:6 1:5 2:4 3:2 4:1
But how change this function for my example(for my big array)?
Tell me please how make this?
How write right?
Very confusing but I think you are looking for something like this. It will give you the index of the array whose first item is greater than the first item in the next array.
foreach($arr as $key => $array) {
if($array[0] > $arr[$key+1][0]) {
echo $key;
}
}
$dates = array();
foreach ($arr as $key => $row) {
$subkeys = array_keys($row); // Elements are one-element associative arrays
$dates[$key] = $row[$subkeys[0]][0]; // Get the element, then get its [0] sub-element
}
array_multisort($dates, SORT_DESC, $arr);
print_r($arr);
$ans_array= array();
// for shuffle array without repeat
for($q=0;$q<count($arr);$q++)
{
$n = rand(0,count($arr));
if($ans_array[$n] == NULL || $ans_array[$n] == '')
{
$ans_array[$n] = $arr[$q];
}
else
{ if($q==0) $q=0;
else $q = $q-1;
}
}

recursively add elements to array and return new array

Let's say I have an array like this:
$my_array = array(1, 2, 3, 4, array(11, 12, 13, 14), 6, 7, 8, array(15, 16, 17, 18), 10);
I want to build a recursive function that returns an array which contains all the even numbers from my_array. I tried something like:
function get_even_numbers($my_array)
{
$even_numbers = array();
foreach($my_array as $my_arr)
{
if(is_array($my_arr)
{
get_even_numbers($my_arr);
foreach($my_arr as $value)
{
if($value % 2 == 0)
{
$even_numbers[] = $value;
}
}
}
}
return even_numbers;
}
But it doesn't works.
Thank you
It's simple:
Check if the input you get into the function is an array.
If it is, that means you have to loop over the values of the array, and call your function (so it is recursive)
Otherwise, just check if the value coming in is even, and add it to an array to return.
That, in PHP, looks like:
function recursive_even( $input) {
$even = array();
if( is_array( $input)) {
foreach( $input as $el) {
$even = array_merge( $even, recursive_even( $el));
}
}
else if( $input % 2 === 0){
$even[] = $input;
}
return $even;
}
Unless it is a thought exercise for your own edification, implementing a recursive function isn't required for this task, which can accomplished instead by using the higher-order, built-in PHP function, array_walk_recursive.
$res = array();
array_walk_recursive($my_array, function($a) use (&$res) { if ($a % 2 == 0) { $res[] = $a; } });
Of course, this could be wrapped in a function:
function get_even_numbers($my_array) {
$res = array();
array_walk_recursive($my_array, function($a) use (&$res) { if ($a % 2 == 0) { $res[] = $a; } });
return $res;
}

Merge every other array php

array one: 1,3,5,7
array two: 2,4,6,8
the array i want would be 1,2,3,4,5,6,7,8
I'm just using numbers as examples. If it was just numbers i could merge and sort but they will be words. So maybe something like
array one: bob,a,awesome
array two: is,really,dude
should read: bob is a really awesome dude
Not really sure how to do this. Does PHP have something like this built in?
You could write yourself a function like this:
function array_merge_alternating($array1, $array2) {
if(count($array1) != count($array2)) {
return false; // Arrays must be the same length
}
$mergedArray = array();
while(count($array1) > 0) {
$mergedArray[] = array_shift($array1);
$mergedArray[] = array_shift($array2);
}
return $mergedArray;
}
This function expects two arrays with equal length and merges their values.
If you don't need your values in alternating order you can use array_merge. array_merge will append the second array to the first and will not do what you ask.
Try this elegant solution
function array_alternate($array1, $array2)
{
$result = Array();
array_map(function($item1, $item2) use (&$result)
{
$result[] = $item1;
$result[] = $item2;
}, $array1, $array2);
return $result;
}
This solution works AND it doesn't matter if both arrays are different sizes/lengths:
function array_merge_alternating($array1, $array2)
{
$mergedArray = array();
while( count($array1) > 0 || count($array2) > 0 )
{
if ( count($array1) > 0 )
$mergedArray[] = array_shift($array1);
if ( count($array2) > 0 )
$mergedArray[] = array_shift($array2);
}
return $mergedArray;
}
Try this function:
function arrayMergeX()
{
$arrays = func_get_args();
$arrayCount = count($arrays);
if ( $arrayCount < 0 )
throw new ErrorException('No arguments passed!');
$resArr = array();
$maxLength = count($arrays[0]);
for ( $i=0; $i<$maxLength; $i+=($arrayCount-1) )
{
for ($j=0; $j<$arrayCount; $j++)
{
$resArr[] = $arrays[$j][$i];
}
}
return $resArr;
}
var_dump( arrayMergeX(array(1,3,5,7), array(2,4,6,8)) );
var_dump( arrayMergeX(array('You', 'very'), array('are', 'intelligent.')) );
var_dump( arrayMergeX() );
It works with variable numbers of arrays!
Live on codepad.org: http://codepad.org/c6ZuldEO
if arrays contains numeric values only, you can use merge and sort the array.
<?php
$a = array(1,3,5,7);
$b = array(2,4,6,8);
$merged_array = array_merge($a,$b);
sort($merged,SORT_ASC);
?>
else use this solution.
<?php
function my_merge($array1,$array2)
{
$newarray = array();
foreach($array1 as $key => $val)
{
$newarray[] = $val;
if(count($array2) > 0)
$newarray[] = array_shift($array2)
}
return $newarray;
}
?>
hope this help
Expects both arrays to have the same length:
$result = array();
foreach ($array1 as $i => $elem) {
array_push($result, $elem, $array2[$i]);
}
echo join(' ', $result);

Categories