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
Related
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
I am getting a Json respond with :
$response = curl_exec($rest);
$json = json_decode($response, true);
I manage to get its values(strings) with :
$foundUserId=$json['results'][0]['userId'];
$foundName=$json['results'][0]['name'];
$foundPhoneNum=$json['results'][0]['phoneNumber'];
But the last value- phoneNumber, is array of strings .
If i try then to loop over it i get nothing(although the array is there in the Json)
foreach ($foundPhoneNum as &$value)
{
print_r($value);
}
What am i doing wrong ?
EDIT :
The json:
Array ( [results] => Array ( [0] => Array ( [action] => message [createdAt] => 2015-11-21T09:36:33.620Z [deviceId] => E18DDFEC-C3C9 [name] => me [objectId] => klMchCkIDi [phoneNumber] => ["xx665542","xxx9446"] [state] => 1 [updatedAt] => 2015-11-22T08:24:46.948Z [userId] => 433011AC-228A-4931-8700-4D050FA18FC1 ) ) )
You might have json as a string inside json. That's why after json_decode() you still have json inside phoneNumber. You have 2 options:
Decode phoneNumber like
$foundPhoneNum=json_decode($json['results'][0]['phoneNumber']);
Build proper initial json. Instead of
{"phoneNumber": "[\"xx665542\",\"xxx9446\"]"}
should be
{"phoneNumber": ["xx665542","xxx9446"]}
There's a couple of ways to debug situations like this as mentioned in the comments; print_r() and var_dump().
var_dump(), although harder to read the first few times, is my favourite because it tells you the data types of each value in the array. This will confirm whether or not the expected string is indeed an array.
An example from the var_dump() documentation:
<?php
$a = array(1, 2, array("a", "b", "c"));
var_dump($a);
And the output is;
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
array(3) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
[2]=>
string(1) "c"
}
}
As you can see it shows array, int and string as the data types.
You might also like to install the Xdebug extension for PHP which dumps more useful error messages and tracebacks. Again harder to read the first few times, but well worth it!
foreach ($foundPhoneNum as $value)
{
print_r($value);
}
There was an extra & before $value. Try this.
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
Why PHP treating "1" as integer in array_merge()
ex.
$arr1 = array( "1"=>1, 2 , 3 );
$arr2 = array( "1"=>1, 2 );
print_r(array_merge( $arr1 , $arr2 ));
var_dump("1");
var_dump(1);
Outputs:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 1
[4] => 2
)
string(1) "1" int(1)
As per array_merge() function :-
If the input arrays have the same string keys, then the later value for that key will overwrite the previous one. If, however, the arrays contain numeric keys, the later value will not overwrite the original value, but will be appended.
This is not array_merge() related, but rather on how array keys are handled by PHP. See http://php.net/manual/en/language.types.array.php for implicit cast of keys.
You simply shouldn't use numeric values as string keys because they are treated as numerical keys.
The most important thing in this case is:
Strings containing valid integers will be cast to the integer type.
E.g. the key "8" will actually be stored under 8. On the other hand
"08" will not be cast, as it isn't a valid decimal integer.
This above is related to PHP arrays as in PHP Arrays manual
You can see it using this sample code:
$arr1 = array( "1"=>1, "01" => 4, 2 , 3 );
var_dump($arr1);
It will return:
array(4) { 1=> int(1) ["01"]=> int(4) [2]=> int(2) [3]=> int(3) }
So your key "1" became numerical key but key "01" is still string key
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