Strange behavior of Array count() - php

I have following Array
$arr = array(1 => 1, "1" => 50);
When I execute count() on it, it gives me strange answer: 1
echo count($arr);
Whereas an array $arr has two elements.
Why?

It is due to Type Casting . Check Example #2 Type Casting and Overwriting example in Arrays .
If multiple elements in the array declaration use the same key, only the last one will be used as all others are overwritten .
$arr = array(1 => 10, "1" => 20);
var_dump( $arr );
Displays :
array (size=1)
1 => int 20
And so :
echo count( $arr );
Displays :
1
Which is correct .

If multiple elements in the array declaration use the same key, only the last one will be used as all others are overwritten.As all the keys in the below example are cast to 1, the value will be overwritten on every new element.
Sample Code:
$array = array(
1 => "a",
"1" => "b"
);
var_dump($array);
echo count($array);
Sample output:
array(1) {
[1]=>
string(1) "b"
}
1
For details have a look here:http://nz1.php.net/manual/en/language.types.array.php

if you change the "1" to "2" it will count 2. The problem is the fact that you choose the first element in the array to be 1 then you choose it to be 50, so in the final, the array will have one element, which is 50.
See it here!

Related

PHP how to insert array into every array in an array with a loop

I have this array:
array(n){
[0]=>
array(3){
["a"]=>int(1)
["b"]=>int(2)
["c"]=>int(3)
}
...
}
and this array:
array(n){
[0]=>
array(m){
["1x"]=>string(someText)
["2x"]=>string(someText)
["3x"]=>string(someText)
....
}
...
}
I would like to combine them to:
array(n){
[0]=>
array(3){
["a"]=>int(1)
["b"]=>int(2)
["c"]=>int(3)
["x"]=>array(m){
["1m"]=>string(someText)
["2m"]=>string(someText)
["3m"]=>string(someText)
...
}
}
...
}
i've tried looking around, but haven't found a solution for that problem i have.
i'd really appreciate ,if someone could point me at solution for this issue i have.
HUGE THANKS for anyone who might help !
If I understood you correctly, you have 2 arrays: main array and a secondary array (which you want to embed).
You want to take the main array, which holds nested arrays in it, and manipulate it by merging each nested array with the secondary array.
Here is a working code:
// The main array, which we will append to
$mainArr = array(
array (
"a" => 1,
"b" => 2,
"c" => 3
),
array (
"d" => 4,
"e" => 5,
"f" => 6
)
);
// The Array we want to embed to each of the nested arrays in $mainArr
$arrayToEmbed = array(
"1x" => "Str1x",
"2x" => "Str2x",
"3x" => "Str3x"
);
// The final result array that will contain the changes
$resultArr = $mainArr;
// Loop over each nested array in $mainArr and merge with $arrayToEmbed
foreach( $mainArr as $key => $nestedArr ){
$resultArr[$key] = array_merge($nestedArr, $arrayToEmbed);
}
// Print final result
print_r($resultArr);

PHP: Does array have key that is value in another array

so for example I have an associative array like
array( "a" => 23, "b" => 48, "c" => 10, "d" => 19 )
Let's call it ArrayA.
And another array (ArrayB) that is
array( "a", "c" )
I want to get ArrayA's keys that do not occur in ArrayB, which would be "b" and "d".
I haven't found anything useful when googling but I assume that there is a php function for that or how would you solve this as fancy as possible?
You can doit with array_diff() and array_keys()
Manual array_diff: http://php.net/manual/en/function.array-diff.php
Manual array_keys: http://php.net/manual/en/function.array-keys.php
With array_diff() the function returns an array containing all the entries from array1 that are not present in any of the other arrays.
And with array_keys() will return the keys, numeric and string, from the array. You can add specific search options with this function to.
<?php
$ArrayA = array("a" => 23, "b" => 48, "c" => 10, "d" => 19);
$ArrayB = array("a", "c");
$result = array_diff(array_keys($ArrayA), $ArrayB);
print_r($result);
?>
Regards

php, array_merge_recursive works well with string keys only

$array1 = [
'1' => '11',
'b' => 1,
3 => 33,
8 => 8
];
$array2 = [
'1' => '22',
'b' => 2,
3 => 44,
9 => 9
];
$merged = array_merge_recursive($array1, $array2);
and the result is:
array(7) {
[0]=>
string(2) "11"
["b"]=>
array(2) {
[0]=>
int(1)
[1]=>
int(2)
}
[1]=>
int(33)
[2]=>
int(8)
[3]=>
string(2) "22"
[4]=>
int(44)
[5]=>
int(9)
}
so lets take a glance: the only part is the 'b' keys, they are actually works. I dont want to overwrite anything of it but putting them together to an array. Thats good! But then keys the other numeric keys (int or string) are screwed up.
I want to have this as result:
[
'1' => ['11', '22']
'b' => [1, 2]
[3] => [33, 44]
[8] => 8,
[9] => 9
]
possible?
EDIT: of course keys "1" and 1 - string vs int key are the same
Let's break down this question into to separate problems:
When a key in the second array exist in the first array, you want to create an array and make the value the first element of that array.
To be honest, I don't know an easy way of solving this. I'm not sure there is one. And even if, I'm not sure you really want it. Such a function will lead to arrays having values that are a string or an array. How would you handle such an array?
Update: Well, there is one. Your example already shows that array_merge_recursive will convert values with a string key into an array. So 1 => 'foo' would be 0 => 'foo', but 'foo' => 'bar' will end up as 'foo' => ['bar']. I really don't understand this behaviour.
Using string keys would help you out in this case, but after learning more about array_merge_recursive I decided to avoid this function when possible. After I asked this question someone filed it as a bug in it since PHP 7.0, since it works differently in PHP 5.x.
You want to keep the keys, while array_merge_resursive doesn't preserve integer keys, while it does for integer keys:
If the input arrays have the same string keys, then the values for
these keys are merged together into an array, and this is done
recursively, so that if one of the values is an array itself, the
function will merge it with a corresponding entry in another array
too. If, however, the arrays have the same numeric key, the later
value will not overwrite the original value, but will be appended.
To make it worse, it handles differently when handling the nested arrays:
$array1 = [30 => [500 => 'foo', 600 => 'bar']];
$array2 = [];
array_merge_recursive($array1, $array2);
//[0 => [500=> 'foo', 600 => 'bar']];
So effectively, array_merge_resursive isn't really resursive.
Using array_replace_resursive solves that problem:
array_replace_recursive($array1, $array2);
//output:
//array:5 [
// 1 => "22"
// "b" => 2
// 3 => 44
// 8 => 8
// 9 => 9
//]
Please note that PHP is very consistent in being inconsistent. While array_merge_recursive isn't recursive, array_replace_recursive doesn't replace (it also appends):
If the key exists in the second array, and not the first, it will be
created in the first array.
In many cases this is desired behavior and since naming functions isn't PHP's strongest point, you can consider this as a minor issue.
Can you rely on a native function to return your exact desired output? No. At least not in any version as of the date of this post (upto PHP8.1).
The good news is that crafting your own solution is very simple.
Code: (Demo)
foreach ($array2 as $key => $value) {
if (!key_exists($key, $array1)) {
$array1[$key] = $value;
} else {
$array1[$key] = (array)$array1[$key];
$array1[$key][] = $value;
}
}
var_export($array1);
I suppose I am less inclined to recommend this output structure because you have potentially different datatypes on a given level. If you were building subsequent code to iterate this data, you'd need to write conditions on every level to see if the data was iterable -- it just feels like you are setting yourself up for code bloat/convolution. I'd prefer a result which has consistent depth and datatypes.

PHP array_diff weirdness

This is such a simple problem but the PHP doc does not explain why it is happening.
I have this code:
var_dump($newattributes); var_dump($oldattributes);
var_dump(array_diff($newattributes, $oldattributes));
For briefity I am going to omit large parts of the structure I am actually using (since each is 117 elements long) and cut to the case.
I have one array called $newattributes which looks like:
array(117){
// Lots of other attributes here
["deleted"] => int(1)
}
And another called $oldattributes which looks like:
array(117){
// Lots of other attributes here
["deleted"] => string(1) "0"
}
Which looks different right? According to array_diff: no. The output I get from array_diff is:
array(0) { }
I have read the documentation page however it says:
Two elements are considered equal if and only if (string) $elem1 ===
(string) $elem2. In words: when the string representation is the same.
And I am not sure how "1" can object equal "0".
So am I seeing some caveat with array_diff I didn't take into consideration?
The problem might reside in the fact that you are using associative arrays : you should try and use the following for associative arrays : array_diff_assoc():
<?php
$newattributes = array(
"deleted" => 1
);
$oldattributes = array(
"deleted" => "0"
);
$result = array_diff_assoc($newattributes, $oldattributes);
var_dump($result);
?>
result :
array(1) {
["deleted"]=>
int(1)
}
It does happen to me too (when there are more values than one)
$new = array('test' => true, 'bla' => 'test' 'deleted' => 1);
$old = array('test' => true, 'deleted' => '0');
For a full array_diff you need to make some extra work, because in default it returns a relative complement
Try this:
array_diff(array_merge($new, $old), array_intersect($new, $old))
Result:
Array
(
[bla] => test
[deleted] => 0
)

What is the reverse of (object) array (key => value) in PHP?

Is there a fast way to return a key when you know its value in PHP?
For example, if you have:
$Numbers = (object) array ( "0" => 0, "1" => 1, "2" => 3, "3" => 7, "4" => 13 );
is there a way to return:
echo re(13); // Print 4
One way I could think of is to build a function specifically for this, but I was wondering if there is a better way.
There is array_search:
$key = array_search(13, (array) $Numbers);
See http://ua2.php.net/array_search
As several other people have mentioned, array_search does what you asked. But if you want an array of ALL the keys that contain the value instead of only the first, you can use array_keys.
print_r(array_keys($Numbers, 13)); // print Array ( [0] => 4 )
http://www.php.net/manual/en/function.array-keys.php
if you are certain that you have unique keys:
$flipped = array_flip($array);
$key = $flipped[$knownValue];
return $key;
Otherwise, use array_search:
return array_search($knownValue, $array);
The first approach may be better if you do a number of lookups, and have unique values. The second approach returns the first matching key in case of multiple values.
http://php.net/array_search
echo array_search($valToSearch, (array) $Numbers);
http://php.net/manual/en/function.array-search.php

Categories