Array keys ,get array values ,then comma separate - php

I have :
$a = array(
0=>'you',
1=>'will',
2=>'be',
3=>'so',
4=>'happy',
5=>'in'
);
$b = array(
0=>'1',
1=>'4',
2=>'5'
); // (KEYS:1,4,5)
I want out the values of $a that matches $b's keys;
so $val would be willhappyin.
And then comma-separate them.. like: will,happy,in without comma after last one.
How can i do this ? :)

$string = implode(",", array_intersect_key($a, array_flip($b)));
EXPLANATION:
array_flip switches the values of $b to keys.
array_intersect_key takes only the entries in $a that are also present in $b.
implode joins the resulting array values together by comma.

$c = array();
foreach($b as $key)
{
$c[] = $a[$key]
}
echo implode(",",$c);

$out_arr = array();
foreach ($b as $k => $v) {
array_push($out_arr, $a[$v]);
}
return join($out_arr, ',');

Related

How to match and replace one array values to another array keys if they both start with the same letters?

I have two arrays:
$array_one = array('AA','BB','CC');
And:
$replacement_keys = array
(
""=>null,
"BFC"=>'john',
"ASD"=>'sara',
"CSD"=>'garry'
);
So far I've tried
array_combine and to make a loop and try to search for values but can't really find a solution to match the keys of the second array with the values of the first one and replace it.
My goal is to make a final output:
$new_array = array
(
''=>null,
'BB' => 'john',
'AA' => 'sara',
'CC' => 'garry'
);
In other words to find a matching first letter and than replace the key with the value of the first array.
Any and all help will be highly appreciated.
Here is a solution keeping both $replacement_keys and $array_one intact
$tempArray = array_map(function($value){return substr($value,0,1);}, $array_one);
//we will get an array with only the first characters
$new_array = [];
foreach($replacement_keys as $key => $replacement_key) {
$index = array_search(substr($key, 0, 1), $tempArray);
if ($index !== false) {
$new_array[$array_one[$index]] = $replacement_key;
} else {
$new_array[$key] = $replacement_key;
}
}
Here is a link https://3v4l.org/fuHSu
You can approach like this by using foreach with in_array
$a1 = array('AA','BB','CC');
$a2 = array(""=>null,"BFC"=>'john',"ASD"=>'sara',"CSD"=>'garry');
$r = [];
foreach($a2 as $k => $v){
$split = str_split($k)[0];
$split .= $split;
in_array($split, $a1) ? ($r[$split] = $v) : ($r[$k] = $v);
}
Working example :- https://3v4l.org/ffRWY

Sort an array of integers according to frequency of elements. If the frequency of two elements are same then they will be printed in ascending order

For example, input array is [9,1,9,1,3,9,1,2,9] output array will be [9,9,9,9,1,1,1,2,3].
Here's what I've tried below but not giving me expected result:
$array = [9,1,9,1,3,9,1,2,9];
$values = array_count_values($array);
arsort($values);
$popular = array_keys($values);
print_r(array_values($popular));
foreach ($values as $key => $val) {
echo $key.", ";
}
Output:
Array
(
[0] => 9
[1] => 1
[2] => 3
[3] => 2
)
9, 1, 3, 2,
If we loop the array_count_values then we can make sure they come in the correct order.
When there is two that is the same count I find all the same with array_intersect then foreach them and add in the correct order.
$array = [9,1,9,1,3,9,1,2,9];
$values = array_count_values($array);
arsort($values);
//var_dump($values);
$result =[];
$same = [];
foreach($values as $key => $val){
if(!in_array($key, array_keys($same))){
if(next($values) != $val){
$result = array_merge($result, array_fill(0, $val, $key));
}else{
$same = array_intersect($values, [$val]);
ksort($same);
foreach($same as $skey => $val){
$result = array_merge($result, array_fill(0, $val, $skey));
}
//var_dump($same);
}
}
}
var_dump($result);
https://3v4l.org/sk44Q
Try usort combined with array_count (php >= 7.0):
$array = [9,1,9,1,3,9,1,2,9];
$arrayCounts = array_count_values($array);
usort($array, function ($a, $b) use ($arrayCounts) {
$countA = $arrayCounts[$a] ?? 0;
$countB = $arrayCounts[$b] ?? 0;
if ($countA == $countB) {
return $a == $b ? 0 : ($a < $b ? -1 : 1);
}
return ($countA > $countB) ? -1 : 1;
});
You could use this sequence:
$arrayCounts = array_count_values($array);
usort($array, function ($a, $b) use ($arrayCounts) {
return $arrayCounts[$b] - $arrayCounts[$a] ?: $a - $b;
});
Now $array is sorted as requested.
The callback function that is passed as argument to usort should return a negative number when the two elements $a and $b should stay in that order (from left to right), or a positive number when they should be reversed. 0 when it does not matter.
The numeric expression that is returned in this particular callback function subtracts the frequencies of $a and $b. If $b occurs more, then that subtraction is positive, and that is returned. Similarly if the subtraction is negative, then that negative value is returned. Now when the frequencies are equal, the ?: operator kicks in and the expression after it is evaluated. That other subtraction also results in a positive or negative value, based on the original value itself. So $a - $b will be negative when $a < $b, which means the order can remain as it is (knowing that we already derived that their frequencies were equal).

merging two arrays with specified index [duplicate]

This question already has answers here:
Transpose and flatten two-dimensional indexed array where rows may not be of equal length
(4 answers)
Closed 5 months ago.
There are two arrays , the second array will always be smaller by 1 from first array. The first array contains the numbers and second array contains the mathematical operators.
$arr1 = [210,11,12];
$arr2 = ['-','/'];
the code which i have written is working on this test case only ,but when i increase the number of elements in it. It fails.
$arr1 = [210,11,12,12];
$arr2 = ['-','/','/'];
the code i have tried so far..
$arr1 = [210,11,12];
$arr2 = ['-','/'];
$arr3 = [];
for($i=0;$i<count($arr1);$i++){
if($i == 0){
$arr3[] = $arr1[0];
}
if ($i % 2 != 0) {
$arr3[] = $arr1[$i];
}
else {
if($i < (count($arr2)-1)){
$arr3[] = $arr2[$i];
}else{
$arr3[] = $arr2[$i-1];
}
}
}
array_push($arr3,end($arr1));
print_r($arr3);
the expected result will be
$arr3 = [210,'-',11,'/','12','/','12']
You can mix the two arrays together by converting columns to rows with array_map, then merging the rows.
$arr3 = array_merge(...array_map(null, $arr1, $arr2));
array_pop($arr3);
The array_map(null, $arr1, $arr2) expression will result in
[[210, '/'], [11, '/'], [12, '/'], [12, null]]
then, array_merge(...) combines all the inner arrays together into one for the final result.
array_pop will remove the trailing null which is there because of the uneven size of the two arrays, but if you're going to end up imploding this and outputting the results as a math expression, you don't need to do it since that won't show up anyway. In fact, if that is the goal you can just add the implode directly to the expression above.
echo implode(' ', array_merge(...array_map(null, $arr1, $arr2)));
Loop the first array and use $key =>.
Then you build the new array in the loop and if $arr2 has a value with the same key, add it after the $arr1 value.
$arr1 = [210,11,12,12];
$arr2 = ['-','/','/'];
foreach($arr1 as $key => $val){
$arr3[] = $val;
if(isset($arr2[$key])) $arr3[] = $arr2[$key];
}
var_dump($arr3);
//[210, -, 11, /, 12, /, 12]
Provided, as you say, that the second array is always larger by one element, then this would be a simple way to do it:
function foo(array $p, array $q): array {
$r = [array_shift($p)];
foreach ($q as $x) {
$r[] = $x;
$r[] = array_shift($p);
}
return $r;
}
print_r(
foo([210,11,12], ['-', '/'])
);
print_r(
foo([210,11,12,12], ['-','/','/'])
);
https://3v4l.org/F0ud8
If the indices of the arrays are well formed, the above could be simplified to:
function foo(array $p, array $q): array {
$r = [$p[0]];
foreach ($q as $i => $x) {
$r[] = $x;
$r[] = $p[$i + 1];
}
return $r;
}
I wanted to offer a couple of approaches that do not modify the original array, accommodate the possibility of empty input arrays, and do not use more than one loop.
By prepopulating the result array with the first value from the numbers array, then iterating the operators array, you can avoid making iterated checks of isset().
Code: (Demo) (Demo without iterated array_push() calls)
$numbers = [210, 11, 12];
$operators = ['-', '/'];
$result = (array)($numbers[0] ?? []);
foreach ($operators as $i => $operator) {
array_push($result, $operator, $numbers[++$i]);
}
var_export($result);
or with array_reduce():
var_export(
array_reduce(
$operators,
function($result, $operator) use($numbers) {
static $i = 0;
array_push($result, $operator, $numbers[++$i]);
return $result;
},
(array)($numbers[0] ?? [])
)
);

What is the best way to go through one column in a multi dimentional array

Suppose I have the array $array where:
$array[0] = {'a','b','c'}
$array[1] = {'d','e','f'}
And I want to iterate over the first column of the nested array in order to get 'a','d' only. What is the most efficient way to do that other than having a loop that iterates on $array[n][0]?
For PHP < 5.3 you can use array_map function like as
$array[0] = ['a','b','c'];
$array[1] = ['d','e','f'];
echo implode(',',array_map(function($v){ return $v[0];},$array));//a,d
As #Rizier123 commented you can simply use array_shift as callback function like as
echo implode(',',array_map('array_shift',$array));//a,d
Demo
Try this -
$array[0] = ['a','b','c'];
$array[1] = ['d','e','f'];
$new = array_column($array, 0);
foreach($new as $v) {
echo $v . ' ';
}
Output
a d
For lower versions of PHP -
$new = array();
foreach($array as $a) {
$new[] = $a[0];
}

Array combine into associative array

I need to add the values of an associative array to another one.
$a = array(4=>2,5=>5);
$b = arrray(array(0=>0,1=>4,2=>10,3=>1000),array()...);
What I'm expecting to get is a third array ($c) like the one below where the content of $b follows the content of $a:
$c = array(array(4=>2,5=>5,0=>0,1=>4,2=>10,3=>1000),array(4=>2,5=>5....));
This is what I've written (not working):
$c = array();
foreach ($possible_opp_action as $sub) {
$c[] = array_push($to_merge,array_values($sub));
}
$a = array(4=>2,5=>5);
$b = array(array(0=>0,1=>4,2=>10,3=>1000),
array(0=>0,1=>40,2=>100,3=>2000),
array(4=>10)
);
$c = array();
foreach($b as $tmp) {
$c[] = $a+$tmp;
}
var_dump($c);
Unlike array_merge, this will maintain numeric keys... but watch out for duplicate keys
$c = array();
foreach ($b as $bb) {
$c[] = array_merge($a,$bb);
}
If you do not need $b in original form:
<?php
$a = array(4=>2,5=>5);
$b = array(array(0=>0,1=>4,2=>10,3=>1000),array());
foreach ($b as &$ref) {
$ref = $a + $ref;
}
var_dump($b);
Otherwise:
<?php
$a = array(4=>2,5=>5);
$b = array(array(0=>0,1=>4,2=>10,3=>1000),array());
$c = array();
foreach ($b as &$ref) {
$c[] = $a + $ref;
}
var_dump($c);
You need array_merge.
http://us.php.net/manual/en/function.array-merge.php
Note the handling of duplicate keys:
Merges the elements of one or more arrays together so that the values of one are appended to the end of the previous one. It returns the resulting array.
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.
EDIT:
I may have not read the question right - please clarify...
Do you want all the array items in a single array, or an array with the original arrays as items in it (an array of arrays)?
IE:
c = array(a=a, b=b, c=c, etc.) <- can be done with array_merge($a, $b, $c, etc)
vs
c = array(
b = array(a=a, b=b, c=c, etc),
a=array(d=d, e=e, etc.)
) <- should be done by just concatenating the next array on the end like this (and skip the $c altogether):
$c[] = $b;
$c[] = $a;
//or
$c = array();
foreach ($possible_opp_action as $sub) {
$c[] = $sub;
}
try
$c = array_merge($b, $a)
help in http://php.net/manual/es/function.array-merge.php

Categories