Multidimensional arrays comparison in PHP - php

When comparing arrays The Documentation says
$a == $b Equality TRUE if $a and $b have the same key/value pairs.
Though when comparing with multidimensional arrays this doesn’t seem to be the case
$a = array(
array("test"),
array("testing"),
);
$b = array(
array("testing"),
array("test"),
);
var_dump($a);
var_dump($b);
var_dump($a == $b);
returns
array(2) {
[0] =>
array(1) {
[0] =>
string(4) "test"
}
[1] =>
array(1) {
[0] =>
string(7) "testing"
}
}
array(2) {
[0] =>
array(1) {
[0] =>
string(7) "testing"
}
[1] =>
array(1) {
[0] =>
string(4) "test"
}
}
bool(false)
Same array, Different order. array diff returns correctly though.
Is this an expected feature ? I know i can compare with array_diff($a,b) + array($b, $a). Im not sure why the == doesnt work though

This is because your arrays are different in the leaf nodes.
In your first array 0 = test and in your second array 0 = testing.

Use === comparison for taking care about keys order.
Check this source:
Compare multidimensional arrays in PHP
regards

== sign allows for comparison of arrays in any order, it will internally use a sort on the master array and do the === comparision.
However it does not do a sort on the sub-arrays, you will need to do that manually before the comparison
NOTE : see == & === difference details here

Related

PHP: difference between stdClass arrays

I have two array of objects:
Array1:
[[0] => stdClass, [1] => stdClass, [2] => stdClass]
Array2
[[0] => stdClass, [1] => stdClass
I want to get the difference between two arrays (Array1-Array2).
Does it exist a better way instead of iterating the two arrays and checking the properties of the objects?
Thanks a lot
You can use classical array_diff, but need to process strings, not objects in arrays that are compared.
So you can map these arrays to JSON strings and them revert this transformation
<?php
$a = [(object)array('a' => 'b'), (object)array('c' => 'd'), (object)array('e' => 'f')];
$b = [(object)array('a' => 'b'), (object)array('g' => 'h')];
var_dump(array_map('json_decode', array_diff(array_map('json_encode', $a), array_map('json_encode', $b))));
This code will print:
array(2) {
[1]=>
object(stdClass)#6 (1) {
["c"]=>
string(1) "d"
}
[2]=>
object(stdClass)#7 (1) {
["e"]=>
string(1) "f"
}
}
So these are elements that exist in $a and absent in $b.
A similar problem is considered under the link:
array_diff() with multidimensional arrays

Remove Numerical Keys from an array in php

I am simply trying to turn this:
Array
(
[0] => 20200330
[1] => 20200329
[2] => 20200328
)
Into this and I am having an extremely hard time
Array
(
20200330,
0200329,
20200328,
)
All arrays in PHP have a unique key for each value within that array.
By default they are 0, 1, 2, 3, etc unless you explicitly set them (e.g. $a = ['key' => 1234];).
It is possible to "remove" keys (set to default without impacting the order) through the use of the array_values() function:
$a = ['a' => 123, 'b' => 321];
$a = array_values($a);
print_r($a); // [0 => 123, 1 => 321]
But it is not possible to entirely remove the keys from an array.
Arrays are by default associated with numbers starting from 0
<?php
$arr=array("String1","String2","Something else");
var_dump($arr);
?>
Output will be:
array(3) {
[0]=>
string(7) "String1"
[1]=>
string(7) "String2"
[2]=>
string(14) "Something else"
}
So if you want to access element of array you type $arr[index] and index is number by default

find, save and remove duplicate values from more then one array

first array
[0]=> Brian
[1]=> A
[2]=> Leo
[3]=> A
[4]=> Mike
second array
[0]=> 1
[1]=> 2
[2]=> 3
[3]=> 4
[4]=> 5
I want to check if in first array there are duplicates, if yes, save only the first occurrence of that value, the other removes, remember those keys, and delete them from the second array too. In the end i want to have
first array
[0]=> Brian
[1]=> A
[2]=> Leo
[3]=> Mike
second array
[0]=> 1
[1]=> 2
[2]=> 3
[3]=> 5
I tried with this but second array does not have duplicates so it won't work for both array:
array_values(array_unique($array));
You did
array_values(array_unique($array));
This will give unique values of $array, but you won't find which index of second array needs to be unset.
Approach #1:
Your best shot is a simple for loop with an isset check. If we find the value already present in our $set(a new temp array), we unset that index from both original arrays, else we preserve it.
Snippet:
<?php
$arr1 = [
'Brian',
'A',
'Leo',
'A',
'Mike'
];
$arr2 = [
1,2,3,4,5
];
$set = [];
foreach($arr1 as $key => $value){
if(!isset($set[$value])) $set[$value] = true;
else{
unset($arr1[$key]); // foreach creates a copy of $arr1, so safe to unset
unset($arr2[$key]);
}
}
print_r($arr1);
print_r($arr2);
Demo: https://3v4l.org/BQ9mA
Approach #2:
If you don't like for loops, you can use array wrappers to do this. You can use array_combine to make first array values as keys and second array values as arrays. Note that this would only preserve the latest key value pairs, so we do a array_reverse to only maintain first occurrence pairs.
Snippet:
<?php
$arr1 = [
'Brian',
'A',
'Leo',
'A',
'Mike'
];
$arr2 = [
1,2,3,4,5
];
$filtered_data = array_combine(array_reverse($arr1),array_reverse($arr2));
print_r(array_keys($filtered_data));
print_r(array_values($filtered_data));
Demo: https://3v4l.org/mlstg
This simply builds a temp array using the values from your 2 arrays.
Because we use values of $a1 as the key, dups get overwritten and therefore lost. The array_keys_exists() check makes sure the first Dup is used and not subsequent dups. Then we just split the array into the two input arrays.
$a1 = ['Brian', 'A', 'Leo', 'A', 'Mike'];
$a2 = [1,2,3,4,5];
#temp array created using values of $a1 as key so dups get dropped because they are reused
foreach ($a1 as $i=>$a) {
if ( ! array_key_exists($a, $new)){
$new[$a] = $a2[$i];
}
}
$a1 = array_keys($new);
$a2 = array_values($new);
print_r($a1);
print_r($a2);
RESULT:
Array
(
[0] => Brian
[1] => A
[2] => Leo
[3] => Mike
)
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 5
)
Please note that array_unique preserves keys so you can easily use it to filter the second array too:
$firstArray = array_unique($firstArray);
$secondArray = array_intersect_key($secondArray, $firstArray);
var_dump(array_values($firstArray), array_values($secondArray));
From the docs of array_unique:
Note that keys are preserved. If multiple elements compare equal under the given sort_flags, then the key and value of the first equal element will be retained.

How to save only numeric numbers from string into an array of int in PHP

in my POST variable i have: print_r($_POST["partecipanti"]);
It displays
["1", "2"]
I want to save only the numbers of the post variable in an int array. I tried
$array = array();
preg_match_all('/-?\d+(?:\.\d+)?+/', $_POST["partecipanti"], $array);
But print_r($array) returns
Array (
[0] => Array (
[0] => 1
[1] => 2
)
)
How can i have a variable like
Array (
[0] => 1
[1] => 2
)
Hope i explained good, thanks all in advance
preg_match_all returns a new multidimensional array every time. But you could just "pop" the array:
$array = array();
preg_match_all('/-?\d+(?:\.\d+)?+/', $_POST["partecipanti"], $array);
$array = $array[0];
Returns:
Array (
[0] => 1
[1] => 2
)
to filter integer values from an array, use array_filter
$arr = array_filter($_POST["participanti"], function($v) { return is_int($v); });
In case you want to convert the array values into integers:
$arr = array_map(function($v) { return (int)$v; }, $_POST["participanti"]);
In both cases the $arr contains only integer values.
Assuming $_POST["partecipanti"]) is a string because you use it directly in your example and the second parameter of preg_match_all is a string.
preg_match_all returns an array where the matches are in the first entry and contains array of strings. You could get that array by using $array[0] .
Besides 1 and 2, your regex -?\d+(?:\.\d+)?+ also matches for example -8.44 or 99999999999999999999999999.
If you want an array of int, you could use array_map with for example the function intval for the callback.
Note the maximum size of an int and the rounding of the values.
For example:
$str = "test 1, test 2, test 2.3 and -8.44 plus 99999999999999999999999999999999999999999999999999";
preg_match_all('/-?\d+(?:\.\d+)?/', $str, $array);
$array = array_map/**/("intval", $array[0]);
var_dump($array);
Demo
That results in:
array(5) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(2)
[3]=>
int(-8)
[4]=>
int(9223372036854775807)
}

How to combine an array with another array

I've two arrays array1 and array2 and I want to add all elements of array2 to the end of array1. array1 contains many items.
The keys are numeric and I don't want this syntax:
array1 = array1 + array2
or
array1 = SomeArrayFun(array1,array2)
As it takes away CPU times ( as array is created twice )
What I want is:
array1 . SomeAddFun(array2); // This will not create any new arrays
Is there any way to do it?
If you'd like to append data to an existing array you should se array_splice.
With the proper arguments you'll be able to insert/append the contents of $array2 into $array1, as in the below example.
$array1 = array (1,2,3);
$array2 = array (4,5,6);
array_splice ($array1, count ($array1), 0, $array2);
print_r ($array1);
output:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
)
You might use ArrayObject with the append function:
$arrayobj = new ArrayObject(array('first','second','third'));
$arrayobj->append('fourth');
Result:
object(ArrayObject)#1 (5) {
[0]=>
string(5) "first"
[1]=>
string(6) "second"
[2]=>
string(5) "third"
[3]=>
string(6) "fourth"
}
Don't know for appending arrays though, as they seem to be appended as a "subarray" and not as part of the whole.
Docs: http://www.php.net/manual/en/arrayobject.append.php

Categories