How does PHP set keys for arrays? - php

I have an array:
$a = array('color' => 'green', 'format' => 'text', 'link_url');
and another:
$b = array('zero', 'one', 'two', 'three', 'test' => 'ok', 'four');
And with array_merge() I have an array like this:
Array
(
[color] => green
[format] => text
[0] => link_url
[1] => zero
[2] => one
[3] => two
[4] => three
[test] => ok
[5] => four
)
Why PHP sets array key as above? Why not like this:
Array
(
[color] => green
[format] => text
[2] => link_url
[3] => zero
[4] => one
[5] => two
[6] => three
[test] => ok
[8] => four
)

That's because numeric IDs are counted separately from seeing indices. The string indices have no number and are not counted.

Quoting from the PHP manual for your original array definitions:
The key is optional. If it is not specified, PHP will use the increment of the largest previously used integer key.
and from the docs on array_merge():
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.
Values in the input array with numeric keys will be renumbered with incrementing keys starting from zero in the result array.
So it's all quite explicitly documented

Well, if you look at the original array, should be clear:
array(3) {
["color"]=>
string(5) "green"
["format"]=>
string(4) "text"
[0]=>
string(8) "link_url"
}

You appear to have assumed an ordering or a congruity with non-numeric keys, which does not exist.
The numeric keys have an order and this is represented in their new values; the string keys are not part of that ordering system and thus do not affect those new numeric values.
This is simply the way it is and it makes complete sense.

Please check the doc :
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.
Values in the input array with numeric keys will be renumbered with incrementing keys starting from zero in the result array.
Ref: http://www.php.net/manual/en/function.array-merge.php

Related

PHP - Store an array returned by a function in an already existing array, one by one

Very simplified example:
function returnArray() {
return array('First','Second','Third');
}
$arr = array('hello','world');
$arr[] = returnArray();
print_r($arr);
I was (wrongly) expecting to see $arr containing 5 elements, but it actually contains this (and I understand it makes sense):
Array
(
[0] => hello
[1] => world
[2] => Array
(
[0] => First
[1] => Second
[2] => Third
)
)
Easily enough, I "fixed" it using a temporary array, scanning through its elements, and adding the elements one by one to the $arr array.
But I guess/hope that there must be a way to tell PHP to add the elements automatically one by one, instead of creating a "child" array within the first one, right? Thanks!
You can use array_merge,
$arr = array_merge($arr, returnArray());
will result in
Array
(
[0] => hello
[1] => world
[2] => First
[3] => Second
[4] => Third
)
This will work smoothly here, since your arrays both have numeric keys. If the keys were strings, you’d had to be more careful (resp. decide if that would be the result you want, or not), because
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.
You are appending the resulting array to previously created array. Instead of the use array merge.
function returnArray() {
return array('First','Second','Third');
}
$arr = array('hello','world');
$arr = array_merge($arr, returnArray());
print_r($arr);

How to sort an array keys according to another array values with PHP

I have a problem in php array. Seems like it won't be very difficult who
have knowledge on array.
I have two arrays
Example:
1st array is:
Array (
[651] => 12
[620] => 10
[681] => 7
[792] => 6
[402] => 5)
1st array is sorted according to the values with descending order.
2nd array is:
Array (
[681] => Blue
[620] => White
[792] => Red
[651] => Green
[402] => Gray)
Both array has similar keys.
Now i want an array that should look like this
Array (
[651] => Green
[620] => White
[681] => Blue
[792] => Red
[402] => Gray)
That means 2nd array keys should be sorted according to the value of the 1st array.
Thank you very much.
You can use array_multisort. But you shouldn't sort the first array beforehand. If the first array sorted separately you should sync it back by sorting it by keys again (using ksort):
// Sync two arrays -- sort by keys.
ksort($array1);
ksort($array2);
// Sort second array accordingly to the first.
array_multisort($array1, SORT_DESC, $array2);
Here is working demo.
Pay attention that, with this approach, both arrays will be sorted in the end, but you will loose the keys, i.e. arrays will be reindexed.

Why PHP lose item value of array?

I have the array with values:
$array1 = array('Boss', 'Lentin', 'Endless');
print_r ($array);
The result will be:
Array ( [0] => Boss [1] => Lentin [2] => Endless
It's ok.
But, if I add two elements to this array with a keys, the "Boss" element will be lost.
$array2 = array("1"=>'Doctor','Boss', 2=>'Lynx', 'Lentin', 'Endless');
print_r ($array2);
The result will be:
Array ( [1] => Doctor [2] => Lynx [3] => Lentin [4] => Endless )
//Where is "BOSS"???
Why?
When php create the array, set Doctor in index 1 and Boss in index 2, but 2=>'Lynx' cause php overwrite index 2 and set Lynx in it.
You can set it after setted index or use index for it. For example like
$array2 = array("1"=>'Doctor', 2=>'Lynx', 'Boss', 'Lentin', 'Endless');
// or
$array2 = array("1"=>'Doctor', 2=>'Boss', 3=>'Lynx', 'Lentin', 'Endless');
When $array is being created, 'Boss' will first be stored in index 2 (Array([2] =>'Boss') which is later overwritten by 'Lynx'
Your issue is index keys
$array2 = array("1"=>'Doctor','Boss', 2=>'Lynx', 'Lentin', 'Endless');
print_r ($array2);
This is because, on index 1 it is already doctor, boss will be second, which will be replaced by Lynx which have same index of 2 where boss will be replaced.
I hope I am clear.
This is expected behaviour from php (see http://php.net/manual/en/language.types.array.php#example-57). In case you need all the values in the array and don't need to work with keys, I recommend to use array_push($array $value). Otherwise you should add all the values with their keys and remember that for PHP 1 and "1" and true are the same values so they will overwrite each other.
array() is a construct with dynamic arguments representing literal arrays. The assignment of the given values to the array structure is done sequentially i.e. one by one from left to right. In your example:
Doctor is assigned to index 1.
Boss is assigned to index 2.
Lynx overwrites index 2.
Lentin and Endless are assigned to index 3 and 4 respectively.
hey #Weltkind first of all i suggest you to read
"http://php.net/manual/en/language.types.array.php",
now come to your answer In php the array key can be string or integer and if you do not mention the key then
default integer is set and the value of next array key is depending on the previous array integer key means
next array key = previous integer key + 1;
In PHP array the same key value will override by the same key
Now lets understand with your array2:
<?php
$array2 = array("1"=>'Doctor','Boss', 2=>'Lynx', 'Lentin', 'Endless');
1) as you started your array with key "1" so the
so for 1st key value is [1] => 'Doctor'
current array like: array([1] => 'Doctor')
now next key = previous integer key(that is 1) + 1 = 2;
2) for 2nd key value is [2] => 'BOSS'
current array like: array([1] => 'Doctor', [2] => 'BOSS')
3) next key = previous integer key(that is 2) + 1 = 3 it will carry
to next key but as next key is [2] => 'Lynx' as you mentioned so at
key [2] the value will be override by value 'BOSS' to 'Lynx'; current
array like : array([1] => 'Doctor', [2] => 'Lynx')
Now the next key we have is [3]
4) for next value the key is [3] => 'Lentin'
current array like : array([1] => 'Doctor', [2] => 'Lynx', [3] =>
'Lentin');
now next key = previous integer key(that is 3) + 1 = 4;
5) for next value the key is [4] => 'Endless'
current array like : array([1] => 'Doctor', [2] => 'Lynx', [3] =>
'Lentin', [4] => 'Endless');
and that is why the final array is like below :
array(
[1] => 'Doctor',
[2] => 'Lynx',
[3] => 'Lentin',
[4] => 'Endless'
);

How to keep the previous values in array after new assignment?

I have an array named $arr = array. Some of its keys has value, like this:
$arr['1'] = 'one';
$arr['2'] = 'two';
$arr['3'] = 'three';
Now I initialize that array with another arry, some thing like this:
$arr = array('4' => 'four', '5' => 'five');
But I need to keep the previous values. I mean is, when I print that array, the output will be like this:
echo '<pre>';
print_r($arr);
/* ---- output:
Array
(
[4] => four
[5] => five
)
*/
While I want this output:
Array
(
[1] => one
[2] => two
[3] => three
[4] => four
[5] => five
)
So, How can I take care of old keys (values) after re-initialized?
Here are your options detailed below: array_merge, union (+ operator), array_push, just set the keys directly and make a function that just loops over the array with your own custom rules.
Sample data:
$test1 = array('1'=>'one', '2'=>'two', '3'=>'three', 'stringkey'=>'string');
$test2 = array('3'=>'new three', '4'=>'four', '5'=>'five', 'stringkey'=>'new string');
array_merge (as seen in other answers) will re-index numeric keys (even numeric strings) back to zero and append new numeric indexes to the end. Non numeric string indexes will overwrite the value where the index exists in the former array with the value of the latter array.
$combined = array_merge($test1, $test2);
Result (http://codepad.viper-7.com/c9QiPe):
Array
(
[0] => one
[1] => two
[2] => three
[stringkey] => new string
[3] => new three
[4] => four
[5] => five
)
A union will combine the arrays but both string and numeric keys will be handled the same. New indexes will be added and existing indexes will NOT be overwritten.
$combined = $test1 + $test2;
Result (http://codepad.viper-7.com/8z5g26):
Array
(
[1] => one
[2] => two
[3] => three
[stringkey] => string
[4] => four
[5] => five
)
array_push allows you to append keys to an array. So as long as the new keys are numeric and in sequential order, you can push on to the end of the array. Note though, non-numeric string keys in the latter array will be re-indexed to the highest numeric index in the existing array +1. If there are no numeric keys, this would be zero. You would also need to reference each new value as a separate argument (see arguments two and three below). Also, since the first argument is taken in by reference, it will modify the original array. The other options allow you to combine to a separate array in case you need the original.
array_push($test1, 'four', 'five');
Result (http://codepad.viper-7.com/5b9nvC):
Array
(
[1] => one
[2] => two
[3] => three
[stringkey] => string
[4] => four
[5] => five
)
You could also just set the keys directly.
$test1['4'] = 'four';
$test1['5'] = 'five';
Or even just make a loop and wrap it in a function to handle your custom rules for merging
function custom_array_merge($arr1, $arr2){
//loop over array 2
foreach($arr2 as $k=>$v){
//if key exists in array 1
if(array_key_exists($arr1, $k)){
//do something special for when key exists
} else {
//do something special for when key doesn't exists
$arr1[$k] = $v;
}
}
return $arr1;
}
The function could be expanded to use stuff like func_get_args to allow any number of arguments.
I'm sure there are also more "hacky" ways to do it using stuff like array_
splice or other array functions. However, IMO, I would avoid them just to keep the code a little more clear about what you are doing.
use array_merge:
$arr = array_merge($arr, array('4' => 'four', '5' => 'five'));
Well, as per the comments (which are correct) this will reindex the array, another solution to avoid that would be to do as follows:
array_push($arr, "four", "five");
But this would not work if you have different keys, like strings that are not masked numbers.
Another way is to use + in order to merge them maintaining keys:
$arr['1'] = 'one';
$arr['2'] = 'two';
$arr['3'] = 'three';
$arr2 = array('4' => 'four', '5' => 'five');
$arr = $arr + $arr2;
Another way to do it, and keeps the keys of the array, is using array_replace.
$arr['1'] = 'one';
$arr['2'] = 'two';
$arr['3'] = 'three';
print_r(array_replace($arr, array('4' => 'four', '5' => 'five')));
Output:
Array
(
[1] => one
[2] => two
[3] => three
[4] => four
[5] => five
)

php assoc array

I have two assoc array i want to creat one array out of that
E.g
a(a=>1
b=>3
f=>5
)
b(a=>4
e=>7
f=>9
)
output must be
c(
a=>1
b=>3
f=>5
a=>4
e=>7
f=>9
)
i am new in php
Use array_merge(). Your resulting array CAN NOT have more than one entry for the same key, so the second a => something will overwrite the first.
Use the + operator to return the union of two arrays.
The new array is constructed from the left argument first, so $a + $b takes the elements of $a and then merges the elements of $b with them without overwriting duplicated keys. If the keys are numeric, then the second array is just appended.
This ey difference of the + operator and the function, array_merge is that array merge overwrites duplicated keys if the latter arguments contain that key. The documentation puts it better:
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.
If the keys are different, then use array_merge()
<?php
$a1=array("a"=>"Horse","b"=>"Cat");
$a2=array("c"=>"Cow");
print_r(array_merge($a1,$a2));
?>
OUTPUT:
Array ( [a] => Horse [b] => Cat [c] => Cow )
If the keys are the same, then use array_merge_recursive()
<?php
$ar1 = array("color" => array("favorite" => "red"), 5);
$ar2 = array(10, "color" => array("favorite" => "green", "blue"));
$result = array_merge_recursive($ar1, $ar2);
print_r($result);
?>
OUTPUT:
Array
(
[color] => Array
(
[favorite] => Array
(
[0] => red
[1] => green
)
[0] => blue
)
[0] => 5
[1] => 10
)

Categories