In a piece of software, I merge two arrays with array_merge function. But I need to add the same array (with the same keys, of course) to an existing array.
The problem:
$A = array('a' => 1, 'b' => 2, 'c' => 3);
$B = array('c' => 4, 'd'=> 5);
array_merge($A, $B);
// result
[a] => 1 [b] => 2 [c] => 4 [d] => 5
As you see, 'c' => 3 is missed.
So how can I merge all of them with the same keys?
You need to use array_merge_recursive instead of array_merge. Of course there can only be one key equal to 'c' in the array, but the associated value will be an array containing both 3 and 4.
Try with array_merge_recursive
$A = array('a' => 1, 'b' => 2, 'c' => 3);
$B = array('c' => 4, 'd'=> 5);
$c = array_merge_recursive($A,$B);
echo "<pre>";
print_r($c);
echo "</pre>";
will return
Array
(
[a] => 1
[b] => 2
[c] => Array
(
[0] => 3
[1] => 4
)
[d] => 5
)
$arr1 = array(
"0" => array("fid" => 1, "tid" => 1, "name" => "Melon"),
"1" => array("fid" => 1, "tid" => 4, "name" => "Tansuozhe"),
"2" => array("fid" => 1, "tid" => 6, "name" => "Chao"),
"3" => array("fid" => 1, "tid" => 7, "name" => "Xi"),
"4" => array("fid" => 2, "tid" => 9, "name" => "Xigua")
);
if you want to convert this array as following:
$arr2 = array(
"0" => array(
"0" => array("fid" => 1, "tid" => 1, "name" => "Melon"),
"1" => array("fid" => 1, "tid" => 4, "name" => "Tansuozhe"),
"2" => array("fid" => 1, "tid" => 6, "name" => "Chao"),
"3" => array("fid" => 1, "tid" => 7, "name" => "Xi")
),
"1" => array(
"0" =>array("fid" => 2, "tid" => 9, "name" => "Xigua")
)
);
so, my answer will be like this:
$outer_array = array();
$unique_array = array();
foreach($arr1 as $key => $value)
{
$inner_array = array();
$fid_value = $value['fid'];
if(!in_array($value['fid'], $unique_array))
{
array_push($unique_array, $fid_value);
unset($value['fid']);
array_push($inner_array, $value);
$outer_array[$fid_value] = $inner_array;
}else{
unset($value['fid']);
array_push($outer_array[$fid_value], $value);
}
}
var_dump(array_values($outer_array));
hope this answer will help somebody sometime.
$A = array('a' => 1, 'b' => 2, 'c' => 3);
$B = array('c' => 4, 'd'=> 5);
$C = array_merge_recursive($A, $B);
$aWhere = array();
foreach ($C as $k=>$v) {
if (is_array($v)) {
$aWhere[] = $k . ' in ('.implode(', ',$v).')';
}
else {
$aWhere[] = $k . ' = ' . $v;
}
}
$where = implode(' AND ', $aWhere);
echo $where;
I just wrote this function, it should do the trick for you, but it does left join
public function mergePerKey($array1,$array2)
{
$mergedArray = [];
foreach ($array1 as $key => $value)
{
if(isset($array2[$key]))
{
$mergedArray[$value] = null;
continue;
}
$mergedArray[$value] = $array2[$key];
}
return $mergedArray;
}
Two entries in an array can't share a key, you'll need to change the key for the duplicate
Related
In a piece of software, I merge two arrays with array_merge function. But I need to add the same array (with the same keys, of course) to an existing array.
The problem:
$A = array('a' => 1, 'b' => 2, 'c' => 3);
$B = array('c' => 4, 'd'=> 5);
array_merge($A, $B);
// result
[a] => 1 [b] => 2 [c] => 4 [d] => 5
As you see, 'c' => 3 is missed.
So how can I merge all of them with the same keys?
You need to use array_merge_recursive instead of array_merge. Of course there can only be one key equal to 'c' in the array, but the associated value will be an array containing both 3 and 4.
Try with array_merge_recursive
$A = array('a' => 1, 'b' => 2, 'c' => 3);
$B = array('c' => 4, 'd'=> 5);
$c = array_merge_recursive($A,$B);
echo "<pre>";
print_r($c);
echo "</pre>";
will return
Array
(
[a] => 1
[b] => 2
[c] => Array
(
[0] => 3
[1] => 4
)
[d] => 5
)
$arr1 = array(
"0" => array("fid" => 1, "tid" => 1, "name" => "Melon"),
"1" => array("fid" => 1, "tid" => 4, "name" => "Tansuozhe"),
"2" => array("fid" => 1, "tid" => 6, "name" => "Chao"),
"3" => array("fid" => 1, "tid" => 7, "name" => "Xi"),
"4" => array("fid" => 2, "tid" => 9, "name" => "Xigua")
);
if you want to convert this array as following:
$arr2 = array(
"0" => array(
"0" => array("fid" => 1, "tid" => 1, "name" => "Melon"),
"1" => array("fid" => 1, "tid" => 4, "name" => "Tansuozhe"),
"2" => array("fid" => 1, "tid" => 6, "name" => "Chao"),
"3" => array("fid" => 1, "tid" => 7, "name" => "Xi")
),
"1" => array(
"0" =>array("fid" => 2, "tid" => 9, "name" => "Xigua")
)
);
so, my answer will be like this:
$outer_array = array();
$unique_array = array();
foreach($arr1 as $key => $value)
{
$inner_array = array();
$fid_value = $value['fid'];
if(!in_array($value['fid'], $unique_array))
{
array_push($unique_array, $fid_value);
unset($value['fid']);
array_push($inner_array, $value);
$outer_array[$fid_value] = $inner_array;
}else{
unset($value['fid']);
array_push($outer_array[$fid_value], $value);
}
}
var_dump(array_values($outer_array));
hope this answer will help somebody sometime.
$A = array('a' => 1, 'b' => 2, 'c' => 3);
$B = array('c' => 4, 'd'=> 5);
$C = array_merge_recursive($A, $B);
$aWhere = array();
foreach ($C as $k=>$v) {
if (is_array($v)) {
$aWhere[] = $k . ' in ('.implode(', ',$v).')';
}
else {
$aWhere[] = $k . ' = ' . $v;
}
}
$where = implode(' AND ', $aWhere);
echo $where;
I just wrote this function, it should do the trick for you, but it does left join
public function mergePerKey($array1,$array2)
{
$mergedArray = [];
foreach ($array1 as $key => $value)
{
if(isset($array2[$key]))
{
$mergedArray[$value] = null;
continue;
}
$mergedArray[$value] = $array2[$key];
}
return $mergedArray;
}
Two entries in an array can't share a key, you'll need to change the key for the duplicate
How to set the key for yielded value? Can the generator have the key as well as array does?
I can easily name keys when returning arrays. It's very useful for PhpUnit dataProviders:
$array = [
'key' => ['value',1,2,3],
'here' => ['a',4,5,6],
'there' => ['b',7,8,9],
];
foreach( $array as $key => $value ){
echo $key."\t=>\t".var_export($value, true)."\n\n\n";
}
but can I do the same using generators?
e.g., how to change the following code?:
function hi()
{
yield ['value',1,2,3];
yield ['a',4,5,6];
yield ['b',7,8,9];
}
$array = hi();
foreach( $array as $key => $value ){
echo $key."\t=>\t".var_export($value, true)."\n\n\n";
}
Currently, the output is:
0 => array (
0 => 'value',
1 => 1,
2 => 2,
3 => 3,
)
1 => array (
0 => 'a',
1 => 4,
2 => 5,
3 => 6,
)
2 => array (
0 => 'b',
1 => 7,
2 => 8,
3 => 9,
)
How can I set the mindful keys for yielded values?
It is easy, yield has documented ability to use keys:
https://www.php.net/manual/en/language.generators.syntax.php
function hi()
{
yield 'key' => ['value',1,2,3];
yield 'here' => ['a',4,5,6];
yield 'there' => ['b',7,8,9];
}
$array = hi();
foreach( $array as $key => $value ){
echo $key."\t=>\t".var_export($value, true)."\n\n\n";
}
The output will have keys, as well as an array does:
key => [
0 => 'value',
1 => 1,
2 => 2,
3 => 3,
]
here => [
0 => 'a',
1 => 4,
2 => 5,
3 => 6,
]
there => [
0 => 'b',
1 => 7,
2 => 8,
3 => 9,
]
I have two example arrays:
$array1 = array(
0 => array("a" => '123', "b" => 234),
1 => array("a" => 'abs', "b" => 234),
2 => array("a" => '123', "b" => 234),
3 => array("a" => 'abs', "b" => 234),
4 => array("a" => '123', "b" => 234),
5 => array("a" => 'abs', "b" => 898),
6 => array("a" => '123', "b" => 234),
7 => array("a" => 'abs', "b" => 234),
8 => array("a" => '123', "b" => 234),
9 => array("a" => 'abs', "b" => 898)
);
$array2 = array(
0 => array("b" => '234', "c" => "Herr"),
1 => array("b" => '898', "c" => "Frau"),
);
Array 1 should be extended by c, depending on the value in b, which is present in both arrays. Finally, array 1 should look like this:
$array3 = array(
0 => array("a" => '123', "b" => 234, "c" => "Herr"),
1 => array("a" => 'abs', "b" => 234, "c" => "Herr"),
2 => array("a" => '123', "b" => 234, "c" => "Herr"),
3 => array("a" => 'abs', "b" => 234, "c" => "Herr"),
4 => array("a" => '123', "b" => 234, "c" => "Herr"),
5 => array("a" => 'abs', "b" => 898, "c" => "Frau"),
6 => array("a" => '123', "b" => 234, "c" => "Herr"),
7 => array("a" => 'abs', "b" => 234, "c" => "Herr"),
8 => array("a" => '123', "b" => 234, "c" => "Herr"),
9 => array("a" => 'abs', "b" => 898, "c" => "Frau")
);
Are there already simple ways to realize this in PHP7.x?
Make an iteration over $array1 using array_walk(). In use() scope pass the filter array prepared (['234' => 'Herr', '898' => 'Frau']) from $array2. In every cycle of the iteration get value from $filter array by the index value of b and set it to $array1's c index. Example:
$filter = array_column($array2, 'c', 'b');
array_walk($array1, function(&$val) use ($filter) {
$val['c'] = $filter[$val['b']];
});
print_r($array1);
Working demo.
One way of doing it would be a loop through foreach, create an array that contains all the b indexes in $array2 by using array_column(). Then use array_search() on that column, and look for the index b of the current iteration of $array1 - that key (from $array2) will tell you which index to choose. Fetch the value and append it to the temporary array, then append the temporary array into $array3.
$array3 = array();
$b_values = array_column($array2, "b");
foreach ($array1 as $v) {
$temp = $v;
$key_2 = array_search($v['b'], $b_values);
$temp['c'] = $array2[$key_2]['c'];
$array3[] = $temp;
}
Live demo at https://3v4l.org/lZHKS
In a piece of software, I merge two arrays with array_merge function. But I need to add the same array (with the same keys, of course) to an existing array.
The problem:
$A = array('a' => 1, 'b' => 2, 'c' => 3);
$B = array('c' => 4, 'd'=> 5);
array_merge($A, $B);
// result
[a] => 1 [b] => 2 [c] => 4 [d] => 5
As you see, 'c' => 3 is missed.
So how can I merge all of them with the same keys?
You need to use array_merge_recursive instead of array_merge. Of course there can only be one key equal to 'c' in the array, but the associated value will be an array containing both 3 and 4.
Try with array_merge_recursive
$A = array('a' => 1, 'b' => 2, 'c' => 3);
$B = array('c' => 4, 'd'=> 5);
$c = array_merge_recursive($A,$B);
echo "<pre>";
print_r($c);
echo "</pre>";
will return
Array
(
[a] => 1
[b] => 2
[c] => Array
(
[0] => 3
[1] => 4
)
[d] => 5
)
$arr1 = array(
"0" => array("fid" => 1, "tid" => 1, "name" => "Melon"),
"1" => array("fid" => 1, "tid" => 4, "name" => "Tansuozhe"),
"2" => array("fid" => 1, "tid" => 6, "name" => "Chao"),
"3" => array("fid" => 1, "tid" => 7, "name" => "Xi"),
"4" => array("fid" => 2, "tid" => 9, "name" => "Xigua")
);
if you want to convert this array as following:
$arr2 = array(
"0" => array(
"0" => array("fid" => 1, "tid" => 1, "name" => "Melon"),
"1" => array("fid" => 1, "tid" => 4, "name" => "Tansuozhe"),
"2" => array("fid" => 1, "tid" => 6, "name" => "Chao"),
"3" => array("fid" => 1, "tid" => 7, "name" => "Xi")
),
"1" => array(
"0" =>array("fid" => 2, "tid" => 9, "name" => "Xigua")
)
);
so, my answer will be like this:
$outer_array = array();
$unique_array = array();
foreach($arr1 as $key => $value)
{
$inner_array = array();
$fid_value = $value['fid'];
if(!in_array($value['fid'], $unique_array))
{
array_push($unique_array, $fid_value);
unset($value['fid']);
array_push($inner_array, $value);
$outer_array[$fid_value] = $inner_array;
}else{
unset($value['fid']);
array_push($outer_array[$fid_value], $value);
}
}
var_dump(array_values($outer_array));
hope this answer will help somebody sometime.
$A = array('a' => 1, 'b' => 2, 'c' => 3);
$B = array('c' => 4, 'd'=> 5);
$C = array_merge_recursive($A, $B);
$aWhere = array();
foreach ($C as $k=>$v) {
if (is_array($v)) {
$aWhere[] = $k . ' in ('.implode(', ',$v).')';
}
else {
$aWhere[] = $k . ' = ' . $v;
}
}
$where = implode(' AND ', $aWhere);
echo $where;
I just wrote this function, it should do the trick for you, but it does left join
public function mergePerKey($array1,$array2)
{
$mergedArray = [];
foreach ($array1 as $key => $value)
{
if(isset($array2[$key]))
{
$mergedArray[$value] = null;
continue;
}
$mergedArray[$value] = $array2[$key];
}
return $mergedArray;
}
Two entries in an array can't share a key, you'll need to change the key for the duplicate
I can't understand how to combine these arrays.
$data = array("a", "b", "c")
$array = array(0 => Array(1 , 2, 3), 1 => Array(4, 5, 6))
I tried different functions such as merge, combine, map..
Result has to be:
array(
'a' => array(1, 4),
'b' => array(2, 5),
'c' => array(3, 6),
)
This should work for you:
<?php
$data = array("a", "b", "c");
$array = array(array(1 , 2, 3), array(4, 5, 6));
$result = array();
foreach($data as $key => $value) {
foreach($array as $innerKey => $innerValue)
$result[$value][] = $innerValue[$key];
}
print_r($result);
?>
Output:
Array (
[a] => Array ( [0] => 1 [1] => 4 )
[b] => Array ( [0] => 2 [1] => 5 )
[c] => Array ( [0] => 3 [1] => 6 )
)
A solution that uses the function array_column() available since PHP 5.5:
$data = array("a", "b", "c");
$array = array(0 => Array(1 , 2, 3), 1 => Array(4, 5, 6));
$result = array();
foreach($data as $i => $v) {
$result[$v] = array_column($array, $i);
}
If you are stuck with a previous version then use Rizier123's solution (it does the same thing with just a little more code.