PHP array_merge empty values always less prioritar - php

My goal is to merge 2 different arrays.
I have table "a" & "b".
Data from table "a" are more prioritar.
PROBLEM: if a key from "a" contains an empty value, I would like to take the one from table "b".
Here is my code:
<?php
$a = array('key1'=> "key1 from prioritar", 'my_problem'=> "");
$b = array('key1'=> "key1 from LESS prioritar", 'key2'=>"key2 from LESS prioritar", 'my_problem'=> "I REACHED MY GOAL!");
$merge = array_merge($b, $a);
var_dump($merge);
Is there a way to do this in one function without doing something like below?
foreach($b as $key => $value)
{
if(!array_key_exists($key, $a) || empty($a[$key]) ) {
$a[$key] = $value;
}
}

You can use array_replace and array_filter
$mergedArray = array_replace($b, array_filter($a));
The result would be:
array(3) {
["key1"]=>
string(19) "key1 from prioritar"
["key2"]=>
string(24) "key2 from LESS prioritar"
["my_problem"]=>
string(18) "I REACHED MY GOAL!"
}

Just array_filter() $a which will remove any item with '' value.
$merge = array_merge($b, array_filter($a));

Related

Convert single array into multidimensional array in PHP?

If I have this array in PHP:
array(3) {
[0]=>
string(5) "first"
[1]=>
string(6) "second"
[2]=>
string(5) "third"
}
How can I convert this single array into a multidimensional array? What is the quickest way? So I can access this array like:
$array["first"]["second"]...
I want to be able to then set a value to this index like:
$array["first"]["second"]["third"] = "example";
I thought that I need a for loop or a recursive function but I have no idea how to start.
It wasn't quite as simple as I had imagined to begin with. The key to it was doing the process backwards - starting with the last array and then wrapping it in more arrays until you get back to the top level.
$array = array("first", "second", "third");
$newArr = array();
//loop backwards from the last element
for ($i = count($array)-1; $i >= 0 ; $i--)
{
$arr = array();
if ($i == count($array)-1) {
$val = "example";
$arr[$array[$i]] = $val;
}
else {
$arr[$array[$i]] = $newArr;
}
$newArr = $arr;
}
var_dump($newArr);
echo "-------".PHP_EOL;
echo $newArr["first"]["second"]["third"];
Demo: http://sandbox.onlinephpfunctions.com/code/0d7fa30fde7126160fbcc0e80e5727f17b19e39f

How to optimize multiple if check for array index check and initialize value 1

I have a string which has "23:22:0"
$string = "23:22:0";
$array = explode(":", $string);
if ($array[0] == 0) {
$array[0] = 1;
}
if ($array[1] == 0) {
$array[1] = 1;
}
if ($array[2] == 0) {
$array[2] = 1;
}
How to avoid multiple if condition check here and i need this condition to be optimised in some best way. Any help is appreciated thanks in advance.
Please check below example. I have commented out your $string variable and tested $string with '0:0:0' value.
Added print_r() to check whether the value is correct or not as we are expecting.
Hope it might be helpful.
//$string = "23:22:0";
$string = "0:0:0";
$array = explode(":", $string);
$array = array(
0 => ($array[0] == 0) ? 1 : $array[0],
1 => ($array[1] == 0) ? 1 : $array[1],
2 => ($array[2] == 0) ? 1 : $array[2],
);
print_r($array);
I wrote this answer because I thought there was an unknown number of items.
OP has now clarified that it's always three items. This is probably a bit overkill for the task at hand.
You can create a new array with 1's and use array_replace to merge it with the original array if you first remove the zero values.
$string = "23:22:0";
$array = explode(":", $string);
$fill = array_fill(0,count($array), 1); //create new array [1,1,1]
$array= array_filter($array); // remove zero values
$array= array_replace($fill,$array); // "merge" the arrays
var_dump($array);
Output:
array(3) {
[0]=>
string(2) "23"
[1]=>
string(2) "22"
[2]=>
int(1)
}
https://3v4l.org/thpfU
With three items in mind you can make the code look better with a loop.
It will perform about the same I believe.
foreach($array as &$val){
if(!$val) $val=1;
}

get the sum and difference of two associate array in php

I have 2 arrays.
arr1 =array('cat'=>5,'dog'=>2);
arr2 = array('cat'=>1,'dog'=>2);
I need to get the sum of 2 arrays and the difference of these arrays.
arr3 = array(cat =>6,dog =>4);
arr4 = array(cat =>4 ,dog =>0);
I tried USING array_merge,array_diff,array_combine
But nothing gives me what i need.
plz help
Assuming we have the same number of like keys in both arrays we can iterate through one or the other and find and work with the corresponding values belonging to the other identified by the same named keys.
<?php
$a1 = array('cat'=>5,'dog'=>2);
$a2 = array('cat'=>1,'dog'=>2);
foreach($a1 as $k => $v)
{
$add[$k] = $v + $a2[$k];
$sub[$k] = $v - $a2[$k];
}
var_dump($add, $sub);
Output:
array(2) {
["cat"]=>
int(6)
["dog"]=>
int(4)
}
array(2) {
["cat"]=>
int(4)
["dog"]=>
int(0)
}
You could always resolve the first problem with array_sum.
Second is more interesting, I'd solve it with an array_map. See it in action here
$subtracted = array_map(function ($x, $y) {
return $x - $y;
}, $arr1, $arr2);
$result = array_combine(array_keys($arr1), $subtracted);
Note that you can also solve the first problem by replacing - with + in the above example.
Also note that array_map tends to be generally more readable.
Simple foreach can do it, below example if some key is missing and just getting difference not in -ve Negative sign, the difference would be 4 not -4 for 1 cat - 5 cat
<?php
$arr1 =array('cat'=>5,'dog'=>2);
$arr2 = array('cat'=>1,'dog'=>2);
$sum= [];
$sub= [];
foreach(array_merge($arr1,$arr2) as $k=>$v){
$a1 = $arr1[$k] ?? 0;
$a2 = $arr2[$k] ?? 0;
$sum[$k] = $a1 + $a2;
$sub[$k] = abs($a1 - $a2);
}
print_r($sum);
print_r($sub);
?>
Live Demo
With simple foreach loop
If some data exist only in single array

(PHP) Checking items in an array

I have an array like this:
Array(a,b,c,a,b)
Now, if I would like to check how many instances of "b" I can find in the array, how would I proceed?
See the documentation for array_count_values(). It seems to be what you are looking for.
$array = array('a', 'b', 'c', 'a', 'b');
$counts = array_count_values($array);
printf("Number of 'b's: %d\n", $counts['b']);
var_dump($counts);
Output:
Number of 'b's: 2
array(3) {
["a"]=> int(2)
["b"]=> int(2)
["c"]=> int(1)
}
Use array_count_values($arr). This returns an associative array with each value in $arr as a key and that value's frequency in $arr as the value. Example:
$arr = array(1, 2, 3, 4, 2);
$counts = array_count_values($arr);
$count_of_2 = $counts[2];
You can count the number of instances by using this function..
$b = array(a,b,c,a,b);
function count_repeat($subj, $array) {
for($i=0;$i<count($array);$i++) {
if($array[$i] == $subj) {
$same[] = $array[$i]; //what this line does is put the same characters in the $same[] array.
}
return count($same);
}
echo count_repeat('b', $b); // will return the value 2
Although there are some fancy ways, a programmer should be able to solve this problem using very basic programming operators.
It is absolutely necessary to know how to use loops and conditions.
$count = 0;
$letters= array("a","b","c","a","b");
foreach ($letters as $char){
if ($char == "b") $count = $count+1;
}
echo $count.' "b" found';
NOT a rocket science.

php pushing pattern from array1 to array2

I have an array that looks something like this
array(7) {
[0]=> "hello,pat1"
[1]=> "hello,pat1"
[2]=> "test,pat2"
[3]=> "test,pat2"
[4]=> "foo,pat3"
[5]=> "foo,pat3"
[6]=> "foo,pat3"
....
}
I would like to push it into another array so the output of the array2 is as follow:
array(7) {
[0]=> "hello,pat1"
[1]=> "test,pat2"
[2]=> "foo,pat3"
[3]=> "foo,pat3"
[4]=> "foo,pat3"
[5]=> "hello,pat1"
[6]=> "test,pat2"
.....
}
What I want is to push them in the following pattern: 1 "pat1" 1 "pat2" and 3 "pat3", and repeat this pattern every 5 elements.
while ( !empty( $array1 ) )
$a = explode(",",$array1[$i]);
if($a[1]=='pat1' &&)
push && unset
elseif($a[1]=='pat2' &&)
push && unset
elseif($a[1]=='pat3' and < 5)
push && unset and reset pattern counter
}
What would be a good way of doing this?
Any idea will be appreciate it.
Time for some fun with the iterators of the Standard PHP Library :-)
<?php
$array1 = array (
"hello1,pat1", "hello2,pat1", "hello3,pat1",
"test1,pat2", "test2,pat2",
"foo1,pat3", "foo2,pat3", "foo3,pat3",
"foo4,pat3", "foo5,pat3", "foo6,pat3"
);
// "group by" patN
$foo = array();
foreach($array1 as $a) {
// feel free to complain about the # here ...to somebody else
#$foo[ strrchr($a, ',') ][] = $a;
}
// split pat3 into chunks of 3
$foo[',pat3'] = array_chunk($foo[',pat3'], 3);
// add all "groups" to a MultipleIterator
$mi = new MultipleIterator(MultipleIterator::MIT_NEED_ANY);
foreach($foo as $x) {
$mi->attachIterator( new ArrayIterator($x) );
}
// each call to $mi->current() will return an array
// with the current items of all registered iterators
foreach ($mi as $x) {
// "flatten" the nested arrays
foreach( new RecursiveIteratorIterator(new RecursiveArrayIterator($x)) as $e) {
echo $e, "\n";
}
echo "----\n";
}
I think I'd set respective counters with respective incrementation. Since php will cast float keys to integers, you can just increment the ,pat3 items with .33 instead of 1. Then, to flatten the result, just use array_merge() with the splat operator.
Code: (Demo)
$array = [
"hello1,pat1",
"hello2,pat1",
"test3,pat2",
"test4,pat2",
"foo5,pat3",
"foo6,pat3",
"foo7,pat3",
];
$counters = [',pat1' => 0, ',pat2' => 0, ',pat3' => 0];
foreach ($array as $value) {
$end = strrchr($value, ',');
$groups[$counters[$end]][] = $value;
$counters[$end] += ($end === ',pat3' ? .33 : 1);
}
var_export(array_merge(...$groups));
Output:
array (
0 => 'hello1,pat1',
1 => 'test3,pat2',
2 => 'foo5,pat3',
3 => 'foo6,pat3',
4 => 'foo7,pat3',
5 => 'hello2,pat1',
6 => 'test4,pat2',
)

Categories