Merge 2 arrays by appending values - php

I have 2 arrays
$a = array('v1'=>1,'v2'=>2,'v3'=>3,'v4'=>4);
$b = array('v1'=>1,'v2'=>2,'v3'=>3,'v4'=>5);
How do I merge them to a single array like this :
Array
(
[v1] => 1
[v2] => 2
[v3] => 3
[v4] => Array
(
[0] => 4
[1] => 5
)
)
I have tried using array_merge & array_merge_recursive.

You can use this code:
$a = array('v1'=>1,'v2'=>2,'v3'=>3,'v4'=>4);
$b = array('v1'=>1,'v2'=>2,'v3'=>3,'v4'=>5);
$c = array();
foreach($a as $m => $n) {
if (($b[$m] != $n))
$c[$m] = array($n, $b[$m]);
else
$c[$m] = $n;
}

$result = array_intersect_assoc($a, $b);
foreach (array_diff_assoc($a, $b) as $k => $v)
$result[$k] = array($v, $b[$k]);
Update:
anubhava's solution is good. It can be simplified like this:
$c = array();
foreach($a as $k => $v)
$c[$k] = $b[$k] == $v ? $v : array($v, $b[$k]);

$a = array('v1'=>1,'v2'=>2,'v3'=>3,'v4'=>4);
$b = array('v1'=>1,'v2'=>2,'v3'=>3,'v4'=>5);
$results = array();
foreach ($a as $key=>$elem) {
$results[$key][] = $elem;
if (!in_array($b[$key], $results[$key])) {
$results[$key][] = $b[$key];
}
}

Related

Map array with initial letter in PHP

I wish to group a word list in an array with the initial letter.
function alpha($str) {
$result[substr($str,0,1)] = $str;
return $result;
}
$a = ['abc','cde','frtg','acf'];
$b = array_map('alpha', $a);
print_r($b);
What I need:
Array
(
[a] => abc,acf
[c] => cde
[f] => frtg
)
What I get:
Array
(
[0] => Array
(
[a] => abc
)
[1] => Array
(
[c] => cde
)
[2] => Array
(
[f] => frtg
)
[3] => Array
(
[a] => acf
)
)
How about that :
$answer = [];
$a = ['abc','cde','frtg','acf'];
foreach($a as $word){
$key = substr($word,0,1);
if (isset($answer[$key])){
$answer[$key] .= "," . $word;
} else {
$answer[$key] = $word;
}
}
Just add a variable $c and loop over arrays of array using two foreach and group by alphabet...
function alpha($str) {
$result[substr($str,0,1)] = $str;
return $result;
}
$a = ['abc','cde','frtg','acf'];
$b = array_map('alpha', $a);
#print_r($b);
$c = [];
foreach ($b as $key => $values) {
foreach ($values as $key => $value) {
if(!isset($c[$key])){
$c[$key]=$value;
}else{
$c[$key].= "," . $value;
}
}
}
echo "<PRE>";
print_r($c);
Outupt:
Array
(
[a] => abc,acf
[c] => cde
[f] => frtg
)
The function array_map maps to the original indexes but you want new indexes and an altered array, if there are more values with the same initial character. Therefore array_map don't work for you. You could create your new array this way:
$a = ['abc','cde','frtg','acf'];
$b = Array();
$c = Array();
foreach( $a as $v )
{
// multidimensional array
$b[substr($v,0,1)][] = $v;
// comma separated string
$c[substr($v,0,1)] = (isset($c[substr($v,0,1)])) ?
$c[substr($v,0,1)].",$v" : $v;
}
If the first character can also be multibyte Unicode such as ° or €, mb_substr() must be used! Solution with foreach:
$result = [];
$a = ['abc','€de','frtg','acf'];
foreach($a as $word){
$key = mb_substr($word,0,1);
$result[$key] = array_key_exists($key,$result)
? ($result[$key].",".$word)
: $word
;
}
Solution with array_reduce():
$result = array_reduce($a,function($carry,$item){
$key = mb_substr($item,0,1);
$carry[$key] = array_key_exists($key,$carry) ? ($carry[$key].",".$item) : $item;
return $carry;
},[]);
var_export($result);
Output:
array (
'a' => 'abc,acf',
'€' => '€de',
'f' => 'frtg',
)
I think your intention is to store each word into arrays according to its first letter. In this case, the multidimensional array is the right choice.
$array = ['abc','cde','frtg','acf'];
$new_array = array();
foreach($array as $v){
$letter = substr($v,0,1);
if(!isset($new_array[$letter])) {$new_array[$letter] = array();}
array_push($new_array[$letter], $v);
}
print_r($new_array);

Any other better logic for this programme

Today in an interview i got the following question to solve without using any inbuilt function eg in_array and etc.I am able to solve the programme but they told me is there any better approach and also they told me the total code is only upto 7 lines.So can anyone tell me any better approach than this:-
<?php
$a = array(1,3,5,2,1,5,11,16);
$b = array(1,4,3,11,12,5,7,18);
$final = [];
for($i=0;$i<count($a);$i++){
$flag = 0;
if($i==0){
$final[] = $a[$i];
} else {
for($j=0;$j<count($final);$j++){
if($a[$i] == $final[$j]){
$flag = 1;
}
}
if($flag==0){
$final[] = $a[$i];
}
for($k=0;$k<count($final);$k++){
if($b[$i] == $final[$k]){
$flag = 1;
}
}
if($flag==0){
$final[] = $b[$i];
}
}
}
echo '<pre>';
print_r($final);
the result would be the final array which would contain unique array of both eg
Array ( [0] => 1 [1] => 3 [2] => 4 [3] => 5 [4] => 2 [5] => 11 [6] => 16 [7] => 18 )
Here is how you could do it without using built-in functions: Collect the values as keys (so they are unique), and then put those keys back as values in the final array:
$a = array(1,3,5,2,1,5,11,16);
$b = array(1,4,3,11,12,5,7,18);
foreach($a as $v) $keys[$v] = 1;
foreach($b as $v) $keys[$v] = 1;
foreach($keys as $k => $v) $final[] = $k;
echo '<pre>';
print_r($final);
See it run on eval.in.
Just set the key as the value and they will overwrite. If the arrays are the same length:
foreach($a as $k => $v) {
$final[$v] = $v;
$final[$b[$k]] = $b[$k];
}
If not, then do it for each array:
foreach(array($a, $b) as $c) {
foreach($c as $v) {
$final[$v] = $v;
}
}
The order and keys won't be the same, but that wasn't stated as a requirement.

php how to sort the values in multiple arrays in the order of frequency

I have an array containing multiple arrays like
$A = array();
$A[0] = array("1","2","3","4","5");
$A[1] = array("1","6","7","8");
$A[2] = array("0","1","3");
I want to sort the values in multiple arrays in the order of frequency and put them into another array let's say $B.
The values in $B is "1","1","1","3","3","0","2","4","5","6","7","8".
$A = array();
$A[0] = array("1","2","3","4","5");
$A[1] = array("1","6","7","8");
$A[2] = array("0","1","3");
//Merging above array in to one array
$merged = array_values(call_user_func_array('array_merge', $A));
//Getting occurrence count
$counts = array_count_values($merged);
//Sort by count
arsort($counts);
//Adding to required array
$B = array();
foreach ($counts as $k => $v)
for($i=1;$i<=$v;$i++)
$B[] = $k;
echo "<pre>";
print_r($B);
echo "</pre>";
Result
Array
(
[0] => 1
[1] => 1
[2] => 1
[3] => 3
[4] => 3
[5] => 0
[6] => 8
[7] => 7
[8] => 5
[9] => 2
[10] => 4
[11] => 6
)
First merge all arrays
$array1 = array("color" => "red", 2, 4);
$array2 = array("a", "b", "color" => "green", "shape" => "trapezoid", 4);
$resultado = array_merge($array1, $array2);
see -> http://php.net/manual/es/function.array-merge.php
Second sort the big array
arsort($resultado );
see -> http://php.net/manual/es/array.sorting.php
Use a hash table to count the frequency of each number, and then store them in the decreasing order of frequency in array $B, like this:
$hash_table = array();
foreach($A as $array){
foreach($array as $value){
if(empty($hash_table[$value])){
$hash_table[$value] = 1;
}else{
$hash_table[$value] += 1;
}
}
}
arsort($hash_table);
$B = array();
foreach($hash_table as $key => $value){
for($i = 0; $i < $value; ++$i){
$B[] = $key;
}
}
var_dump($B); // to see the contents of array $B
If order of same occurance count items isn't important, you can use:
// Merge all arrays
$counts = array_count_values(call_user_func_array('array_merge', $A));
// Sort by occurance
arsort($counts);
// Add [value] to new array [occurance] times
$B = array();
array_walk($counts, function($occurances, $value) use (&$B){
for($i=0;$i<$occurances;$i++) $B[] = $value;
});
echo implode(',', $B);
Output
1,1,1,3,3,0,8,7,5,2,4,6
Array print in order of count and index:
$temp = array();
foreach($A as $b){
foreach($b as $c){
if(isset($tmep[$c])){
$tmep[$c]++;
}else{
$tmep[$c] = 1;
}
}
}
function SortArrayByKeyThanValue (&$pArray, $pSortMethodForKey = SORT_ASC, $pSortMethodForValue = SORT_DESC){
# check user input: sorting is not necessary
if (count($pArray) < 2)
return;
# define $k and $v as array_multisort() needs real variables, as user input is put by reference
$k = array_keys ($pArray);
$v = array_values($pArray);
array_multisort(
$v, $pSortMethodForValue,
$k, $pSortMethodForKey
);
$pArray = array_combine($k, $v);
}
SortArrayByKeyThanValue($tmep);
$B = array();
array_walk($tmep, function($occurances, $value) use (&$B){
for($i=0;$i<$occurances;$i++) $B[] = $value;
});
echo implode(',', $B);

Merge array values for same keys inside loop with php

Going through foreach loop for filter on my site I get array back like this:
Array
(
[21] => Blau
[24] => Azul
[28] => Blue
)
By choosing next filter another array will be created:
Array
(
[21] => Grün
[24] => Verde
[28] => Green
)
and so on...
What I what to do is merge values of these arrays on same keys. So it have to be look like this:
Array
(
[21] => Blau-Grün
[24] => Azul-Verde
[28] => Blue-Green
)
It worked with Uchiha's code. I made some changed inside my loop:
foreach (...){
//some logic before
$array[] = array();
$i = 0;
foreach($array as $k => $v){
$i++;
foreach($array[$k] as $key => $value){
if(array_key_exists($key, $array[$i])){
$result[$key] = $value . '-' . $array[$i][$key];
}
}
}
echo '<pre>' . print_r($result,true) . '</pre>';
}
$maxItems = max(count($blue),count($green));
for ($i = 0; $i < $maxItems; $i++) {
if (isset($blue[$i], $green[$i])) {
$combined[$i] = $blue[$i].'-'.$green[$i];
} else {
if (isset($blue[$i])) {
$combined[$i] = $blue[$i];
} else {
$combined[$i] = $green[$i];
}
}
}
You can use foreach along with array_key_exists as
foreach($arr1 as $key => $value){
if(array_key_exists($key, $arr2)){
$result[$key] = $value.'-'.$arr2[$key];
}
}
Fiddle
you can use array_map with a closure that joins the two values, e.g.
$joined = array_map(function($m, $n){ return $m . '-' . $n; }, $array1, $array2);
$foo = array(1 => "Bob", 2 => "Sepi");
$bar = array(1 => "sach", 2 => "john");
$foobar= array();
foreach ($foo as $key => $value) {
foreach ($bar as $key1 => $value1) {
if($key == $key1){
$foobar[] = $value."-".$value1;
}
}}
You can create a function, which takes both of arrays as parameter and identify which one has more elements, loop through and concat the string from another array at the same key.
$array1 = array(
'Blau',
'Azul',
'Blue'
);
$array2 = array(
'Grün',
'Verde',
'Green'
)
function mergeArray($array1, $array2){
$newArray = array();
if(count($array1) >= count($array2)){
foreach($array1 as $key => $value){
$newArray[] = $value . (array_key_exists($key, $array2) ? '-' . $array2[$key] : '');
}
} else {
foreach($array2 as $key => $value){
$newArray[] = $value . (array_key_exists($key, $array1) ? '-' . $array1[$key] : '');
}
}
}
$newArray = mergeArray($array1, $array2);
$newArray contains the result you expected.
here is simple and tested code
<?php
$a1=array(
1 => 'Blau',
2 => 'Azul',
3 => 'Blue'
);
$a2=array
(
1 => 'Grün',
2 => 'Verde',
4 => 'Green'
);
$a3=$a1 + $a2;
$a4=$a2 + $a1;
foreach($a3 as $key=>$val){
if($a4[$key] != $a3[$key]){
$a3[$key] = $a3[$key].' '.$a4[$key];
}
}
print_r($a3);
?>

Array Implode in php

I have an array of the following format:
$var = Array
(
[0] => Array
(
[name] => Harry
)
[1] => Array
(
[name] => Wayne
)
)
Array
(
[0] => Array
(
[name] => Wayne
)
I want to implode this array such that i get it in the format:
Harry,Wayne
Wayne
From What I have Tried I am getting it in format:
Harry,Wayne
Harry,Wayne,Wayne
What I have Tried (Not important as its wrong)
foreach($var as $a){
foreach($a as $b){
}$c[] = $b
}
$imp = implode(',',$c);
$var is fetched from database using fetch_array.
$this->db->select('name');
$this->db->where('id', $Id);
$this->db->from('info');
$row = $this->db->get();
$var = $row->result_array();
where $Id is array containing certain user ids.
foreach($var as $a)
{
unset($temp);
foreach($a as $b)
{
$temp[] = $b['name'];
}
$c[] = implode(",", $temp);
}
// output all the names
foreach ($c as $csvNames)
{
echo $csvNames;
}
Try this.
foreach($var as $a){
$m = '';
$delim = '';
foreach($a as $k){
$m .= $delim . $k['name'];
$delim = ',';
}
$c[] = $m;
}
foreach($c as $d){
echo $d;
}
Please ignore those hard-coded loops. There is a recursive function for it.
array_walk_recursive($var, create_function('$val, $key', 'array_push($obj, $val);'), &$output);
echo implode(",",$output);

Categories