How to merge array and preserve keys? - php

I have two arrays:
$array1 = array('a' => 1, 'b' => 2, 'c' => 3);
$array2 = array('d' => 4, 'e' => 5, 'f' => 6, 'a' => 'new value', '123' => 456);
I want to merge them and keep the keys and the order and not re-index!!
How to get like this?
Array
(
[a] => new value
[b] => 2
[c] => 3
[d] => 4
[e] => 5
[f] => 6
[123] => 456
)
I try to array_merge() but it will not be preserved the keys:
print_r(array_merge($array1, $array2));
Array
(
[a] => 'new value'
[b] => 2
[c] => 3
[d] => 4
[e] => 5
[f] => 6
[0] => 456
)
I try to the union operator but it will not overwriting that element:
print_r($array1 + $array2);
Array
(
[a] => 1 <-- not overwriting
[b] => 2
[c] => 3
[d] => 4
[e] => 5
[f] => 6
[123] => 456
)
I try to swapped place but the order is wrong, not my need:
print_r($array2 + $array1);
Array
(
[d] => 4
[e] => 5
[f] => 6
[a] => new value
[123] => 456
[b] => 2
[c] => 3
)
I dont want to use a loop, is there a way for high performance?

You're looking for array_replace():
$array1 = array('a' => 1, 'b' => 2, 'c' => 3);
$array2 = array('d' => 4, 'e' => 5, 'f' => 6, 'a' => 'new value', '123' => 456);
print_r(array_replace($array1, $array2));
Available since PHP 5.3.
Update
You can also use the union array operator; it works for older versions and might actually be faster too:
print_r($array2 + $array1);

Let suppose we have 3 arrays as below.
$a = array(0=>['label'=>'Monday','is_open'=>1],1=>['label'=>'Tuesday','is_open'=>0]);
$b = array(0=>['open_time'=>'10:00'],1=>['open_time'=>'12:00']);
$c = array(0=>['close_time'=>'18:00'],1=>['close_time'=>'22:00']);
Now, if you want to merge all these array and want a final array that have all array's data under key 0 in 0 and 1 in 1 key as so on.
Then you need to use array_replace_recursive PHP function, as below.
$final_arr = array_replace_recursive($a, $b , $c);
The result of this will be as below.
Array
(
[0] => Array
(
[label] => Monday
[is_open] => 1
[open_time] => 10:00
[close_time] => 18:00
)
[1] => Array
(
[label] => Tuesday
[is_open] => 0
[open_time] => 12:00
[close_time] => 22:00
)
)
Hope the solution above, will best fit your requirement!!

#Jack uncovered the native function that would do this but since it is only available in php 5.3 and above this should work to emulate this functionality on pre 5.3 installs
if(!function_exists("array_replace")){
function array_replace(){
$args = func_get_args();
$ret = array_shift($args);
foreach($args as $arg){
foreach($arg as $k=>$v){
$ret[(string)$k] = $v;
}
}
return $ret;
}
}

array_replace_recursive() or array_replace() is the function you are looking for
$array1 = array('a' => 1, 'b' => 2, 'c' => 3);
$array2 = array('d' => 4, 'e' => 5, 'f' => 6, 'a' => 'new value', '123' => 456);
var_dump(array_replace_recursive($array1, $array2));
Demo

I think this might help if i understand properly:
foreach ($i = 0, $num = count($array2); $i < $num; $i++)
{
$array = array_merge($array1, $arrar2[$i]);
}

Related

Consolidate differently structured arrays into one without rearranging keys or values

I have a page that has 4 widgets each getting data from the database. Each widgets gets data in different formats since i have a table widget, a statistics widget and a widget with just one value.
Supposing i have the results of queries returning data say in this format
$arr1 = array(1, 3, 5);
$arr2 = array(2, 4, 6);
$test1 = array(
'11' => '11',
'22' => '22',
'33' => '33',
'44' => '44'
);
$array1 = array(0 => 'zero_a', 2 => 'two_a', 3 => 'three_a');
$array2 = array(1 => 'one_b', 3 => 'three_b', 4 => 'four_b');
how can i pass the arrays as json encoded as one but retains their array structure on the client side for easier and faster creating on widget views?.
I have looked at array_merge and according to the docs, that's not what i am looking for.
how can i pass the arrays as json encoded as one but retains their array structure on the client side for easier and faster creating on widget views?.
You might arrange each array to be json encoded together like so:
$bundle = json_encode([$arr1, $arr2, $test1, $array1, $array2]);
Result:
[[1,3,5],[2,4,6],{"11":"11","22":"22","33":"33","44":"44"},{"0":"zero_a","2":"two_a","3":"three_a"},{"1":"one_b","3":"three_b","4":"four_b"}]
If I understood your issue correctly, you can assign your arrays to a multidimensional array.
Based in your example:
$dataArray = [];
$arr1 = array(1, 3, 5);
$arr2 = array(2, 4, 6);
$dataArray['data_type_one'][] = $arr1;
$dataArray['data_type_one'][] = $arr2;
$test1 = array(
'11' => '11',
'22' => '22',
'33' => '33',
'44' => '44'
);
$dataArray['data_type_two'] = $test;
$array1 = array(0 => 'zero_a', 2 => 'two_a', 3 => 'three_a');
$array2 = array(1 => 'one_b', 3 => 'three_b', 4 => 'four_b');
$dataArray['data_type_three'][] = $array1;
$dataArray['data_type_three'][] = $array2;
You will end up with this array structure:
Array
(
[data_type_one] => Array
(
[0] => Array
(
[0] => 1
[1] => 3
[2] => 5
)
[1] => Array
(
[0] => 2
[1] => 4
[2] => 6
)
)
[data_type_two] => Array
(
[11] => 11
[22] => 22
[33] => 33
[44] => 44
)
[data_type_three] => Array
(
[0] => Array
(
[0] => zero_a
[2] => two_a
[3] => three_a
)
[1] => Array
(
[1] => one_b
[3] => three_b
[4] => four_b
)
)
)
Then, in your views, you can do whatever you need:
foreach ($arrayData['data_type_one'] as $someData) {
echo $someData[0] . ' ';
//will print 1 2
}
echo $dataArray['data_type_two']['11'];
//will print 11

PHP array sorting not working as expected

Below is an output of my array
$array1 = Array ( [d] => 5 [e] => 1 [a] => 3 [b] => 3 [c] => 3 [f] => 3 )
I want to sort it like...
Array ( [d] => 5 [a] => 3 [b] => 3 [c] => 3 [f] => 3 [e] => 1)
I am using arsort($array1)
which results in var_dump($array1)
array (size=6)
'd' => int 5
'f' => int 3
'c' => int 3
'a' => int 3
'b' => int 3
'e' => int 1
anyways to fix this?
Try this :
$array1 = [
'd' => 5,
'e' => 1,
'a' => 3,
'b' => 3,
'c' => 3,
'f' => 3
];
array_multisort(array_values($array1), SORT_DESC, array_keys($array1), SORT_ASC, $array1);
print_r($array1);
Here first array_values($array1), SORT_DESC will sort the values in descending order and then array_keys($array1), SORT_ASC will sort the keys into ascending order and finally both the thing applies to the main array i.e. $array1.
O/P - Array ( [d] => 5 [a] => 3 [b] => 3 [c] => 3 [f] => 3 [e] => 1 )
I hope this time I get what you want. Finger crossed !!!
you can work like this its working.
<?php
$array1 = array( "[d]" => 5,"[e]" => 1,"[a]" => 3,"[b]" => 3,"[c]" => 3,"[f]" => 3 );
$a = arsort($array1);
foreach($array1 as $x => $x_value) {
echo "Key=" . $x . ", Value=" . $x_value;
echo "<br>";
}
?>
output:
Key=[d], Value=5
Key=[f], Value=3
Key=[c], Value=3
Key=[a], Value=3
Key=[b], Value=3
Key=[e], Value=1
You can use uasort for this.
$array = array('d' => 5, 'e' => 1, 'a' => 3, 'b' => 3, 'c' => 3, 'f' => 3);
function cmp($a, $b) {
if ($a == $b) {
return 0;
}
return ($a > $b) ? -1 : 1;
}
uasort($array, 'cmp');
print_r($array);
I tested the code and surely it will work for you.

Inline array concatenation?

Is it possible to concatenate an array using inline code (i.e. inside the array declaration)?
For instance:
function get_array() {
return array('four' => 4, 'five' => 5);
}
$arr = array(
'one' => 1,
'two' => 2,
'three' => 3,
get_array()
);
var_dump($arr);
will result in:
Array(
[one] => 1
[two] => 2
[three] => 3
[0] => Array(
[four] => 4
[five] => 5
)
)
Whereas the desired result would be:
Array(
[one] => 1
[two] => 2
[three] => 3
[four] => 4
[five] => 5
)
Use array_merge(). It is an extra step but since you can't do this during the array declaration it is the next best thing.
$new_array = array_merge($arr, array('four' => 4, 'five' => 5));
print_r($new_array);
Array ( [one] => 1 [two] => 2 [three] => 3 [four] => 4 [five] => 5 )
See it in action

Merge two multidimensional arrays and reindex all subarrays

I have two arrays, I want to merge these two arrays into single array. Please view the detail below:
First Array:
Array
(
[0] => Array
(
[a] => 1
[b] => 2
[c] => 3
)
[1] => Array
(
[a] => 3
[b] => 2
[c] => 1
)
)
Second Array:
Array
(
[0] => Array
(
[d] => 4
[e] => 5
[f] => 6
)
[1] => Array
(
[d] => 6
[e] => 5
[f] => 4
)
)
I want this result. Does somebody know how to do this?
Array
(
[0] => Array
(
[0] => 1
[1] => 2
[2] => 3
)
[1] => Array
(
[0] => 3
[1] => 2
[2] => 1
)
[2] => Array
(
[0] => 4
[1] => 5
[2] => 6
)
[3] => Array
(
[0] => 6
[1] => 5
[2] => 4
)
)
Hope you have understand the question.
Thank you in advance.
Try array_merge:
$result = array_merge($array1, $array2);
FIXED (again)
function array_merge_to_indexed () {
$result = array();
foreach (func_get_args() as $arg) {
foreach ($arg as $innerArr) {
$result[] = array_values($innerArr);
}
}
return $result;
}
Accepts an unlimited number of input arrays, merges all sub arrays into one container as indexed arrays, and returns the result.
EDIT 03/2014: Improved readability and efficiency
more simple and modern way is:
$merged = $array1 + ['apple' => 10, 'orange' => 20] + ['cherry' => 12, 'grape' => 32];
new array syntax from php 5.4
If you want to return the exact result you specify in your question then something like this will work
function array_merge_no_keys() {
$result = array();
$arrays = func_get_args();
foreach( $arrays as $array ) {
if( is_array( $array ) ) {
foreach( $array as $subArray ) {
$result[] = array_values( $subArray );
}
}
}
return $result;
}
As a purely native function solution, merge the arrays, then reindex each subarray.
Code: (Demo)
$a = [
['a' => 1, 'b' => 2, 'c' => 3],
['a' => 3, 'b' => 2, 'c' => 1],
];
$b = [
['d' => 4, 'e' => 5, 'f' => 6],
['d' => 6, 'e' => 5, 'f' => 4],
];
var_export(
array_map('array_values' array_merge($a, $b))
);
Output:
array (
0 =>
array (
0 => 1,
1 => 2,
2 => 3,
),
1 =>
array (
0 => 3,
1 => 2,
2 => 1,
),
2 =>
array (
0 => 4,
1 => 5,
2 => 6,
),
3 =>
array (
0 => 6,
1 => 5,
2 => 4,
),
)

php, how to jumble / randomize order of associative array while keeping key/value pairs

what is the php function to randomize the associative array while keeping key/values pairs. I don't mean to just randomly pick out a key value pair, but actually changing the array (similar to the uasort function, but not in order).
TIA
example:
original array
(
[a] => 4
[b] => 8
[c] => -1
[d] => -9
[e] => 2
[f] => 5
[g] => 3
[h] => -4
)
random ordered array
(
[d] => -9
[a] => 4
[b] => 8
[c] => -1
[h] => -4
[e] => 2
[g] => 3
[h] => -4
[f] => 5
)
Edit
Comparison between 2 solutions.
$start = microtime(true);
$array = array('a' => 4, 'b' => 8, 'c' => -1, 'd' => -9, 'e' => 2, 'f' => 5, 'g' => 3, 'h' => -4);
$shuffleKeys = array_keys($array);
shuffle($shuffleKeys);
$newArray = array();
foreach($shuffleKeys as $key) {
$newArray[$key] = $array[$key];
}
print_r ($newArray);
$elapsed = microtime(true) - $start;
echo "<br>array values took $elapsed seconds.<br>";
$start = microtime(true);
$array = array('a' => 4, 'b' => 8, 'c' => -1, 'd' => -9, 'e' => 2, 'f' => 5, 'g' => 3, 'h' => -4);
$keys = array_keys( $array );
shuffle( $keys );
print_r(array_merge( array_flip( $keys ) , $array ));
$elapsed = microtime(true) - $start;
echo "<br>array values took $elapsed seconds.<br>";
Array ( [h] => -4 [e] => 2 [b] => 8 [d] => -9 [a] => 4 [c] => -1 [f] => 5 [g] => 3 )
array values took 3.0994415283203E-5 seconds.
Array ( [e] => 2 [a] => 4 [d] => -9 [c] => -1 [g] => 3 [f] => 5 [b] => 8 [h] => -4 )
array values took 4.2915344238281E-5 seconds.
You could use shuffle() on array_keys, then loop around your array adding them to the list in the new order.
E.g.
$shuffleKeys = array_keys($array);
shuffle($shuffleKeys);
$newArray = array();
foreach($shuffleKeys as $key) {
$newArray[$key] = $array[$key];
}
A comment on shuffle() might do the trick: http://ch2.php.net/manual/en/function.shuffle.php#104430
<?php
function shuffle_assoc( $array )
{
$keys = array_keys( $array );
shuffle( $keys );
return array_merge( array_flip( $keys ) , $array );
}
?>

Categories