Counting blanks when merging assoctiative arrays - php

I'm trying to merge these 2 arrays
$arr1 = array('a' => "1", 'b' => "2", 'c' => "3");
$arr2 = array('a' => "9", 'b' => "8", 'd' => "7");
into an array that looks like this
$arr1 = array(
'a' => array("1", "9"),
'b' => array("2", "8"),
'c' => array("3", ""),
'd' => array("", "7")
);
The tricky part is the blanks. I need to preserve them in place.
Thanks

function merge()
{
$array_of_arrays = func_get_args();
//get all the unique keys
$final_array_keys = array_keys( call_user_func_array( "array_merge", $array_of_arrays ) );
//make final array
$final_array = array();
foreach( $final_array_keys as $key ) {
foreach( $array_of_arrays as $current_array ) {
$final_array[$key][] = array_key_exists( $key, $current_array ) ? $current_array[$key] : "";
}
}
return $final_array;
}

Try this:
$arr1 = array('a' => "1", 'b' => "2", 'c' => "3");
$arr2 = array('a' => "9", 'b' => "8", 'd' => "7");
$keys = array();
$merged = array()
for($arr1 as $key=>$val)
{
array_push($keys,$key);
}
for($arr2 as $key=>$val)
{
array_push($keys,$key);
}
for($key in keys)
{
$merged[$key] = array("","");
if(isset($arr1[$key])) $merged[$key][0] = $arr1[$key];
if(isset($arr2[$key])) $merged[$key][1] = $arr2[$key];
}

foreach (array_merge($arr1, $arr2) as $key => $val)
{
$result[$key] = array("{$arr1[$key]}", "{$arr2[$key]}");
}
var_dump($result);

here's my suggestion. It'll combine an arbitrary number of arrays according to what you described.
error_reporting(E_ALL | E_STRICT);
header('Content-Type: text/plain');
$arr1 = array('a' => "1", 'b' => "2", 'c' => "3");
$arr2 = array('a' => "9", 'b' => "8", 'd' => "7");
$arr = combine($arr1, $arr2);
print_r($arr);
function combine() {
$keys = array();
foreach (func_get_args() as $arr) {
if (is_array($arr)) {
$keys += $arr;
}
}
$keys = array_keys($keys);
$values = array_pad(array(), count($keys), array());
$ret = array_combine($keys, $values);
foreach (func_get_args() as $arr) {
foreach ($keys as $k) {
$v = array_key_exists($k, $arr) ? $arr[$k] : '';
array_push($ret[$k], $v);
}
}
return $ret;
}
Output:
Array
(
[a] => Array
(
[0] => 1
[1] => 9
)
[b] => Array
(
[0] => 2
[1] => 8
)
[c] => Array
(
[0] => 3
[1] =>
)
[d] => Array
(
[0] =>
[1] => 7
)
)

I like cletus's approach, so I've just made sure it works :)
function combine() {
$keys = array();
foreach (func_get_args() as $arr) {
if (is_array($arr)) {
$keys = array_merge($keys, array_keys($arr));
}
}
$keys = array_unique($keys);
$values = array_pad(array(), count($keys), array());
$ret = array_combine($keys, $values);
foreach (func_get_args() as $arr) {
foreach ($keys as $k) {
$v = '';
if (array_key_exists($k, $arr)){
$v = $arr[$k];
}
array_push($ret[$k], $v);
}
}
return $ret;
}

Related

PHP array: Conditional sum

I have a an array looking like this:
$array = array("a1" => 0, "a2" => 2, "a3" => 1, "b1" => 2, "b2" => 3);
I would like to sum values foreach "unique" key when only the first character is considered. The result should then be:
$newarray = array("a" => 3, "b" => 5);
I have tried using a foreach() loop within another foreach() loop like this:
foreach ($xml->children() as $output) {
foreach ($array as $key => $value) {
if (substr($key,0,1) == $output->KEY) {
$sum += $value; echo $sum;
}
}
}
It didn't work as the results apparently added the prior calculations.
Simple solution:
$final_array=[];
foreach($array as $key=>$value){
$final_array[$key[0]] = (isset($final_array[$key[0]])) ? $final_array[$key[0]]+$value : $value;
}
print_r($final_array);
Output:- https://3v4l.org/tZ4Ei
You can try this one. It will take first letter from your key and make sum of all values with that first letter keys.
<?php
$sum = [];
foreach ($array as $key => $value) {
$letter = substr($key,0,1);
if (!isset($sum[$letter])){$sum[$letter] = 0;}
$sum[$letter] += $value;
}
var_dump($sum);
A simple isset should do it:
$array = array("a1" => 0, "a2" => 2, "a3" => 1, "b1" => 2, "b2" => 3);
$result = array();
foreach ($array as $oldkey => $val) {
$newkey = substr($oldkey, 0, 1);
if (isset($result[$newkey]) === false)
$result[$newkey] = $val;
else
$result[$newkey] += $val;
}
var_dump($result);
Try this way
$array = array('a1' => 0, 'a2' => 2, 'a3' => 3, 'b1' => 2, 'b2' => 3);
$result = array();
foreach($array as $key => $value){
if(isset($result[$key[0]])){
$result[$key[0]] = $result[$key[0]]+$value;
} else {
$result[$key[0]] = $value;
}
}
print_r($result);
Quick and Easy, you can have any number of numbers in the array after the characters.
<?php
$array = ["a1" => 0, "a2" => 2, "a3" => 1, "b1" => 2, "b2" => 3];
$newArray = [];
foreach ($array as $key => $value) {
$key = preg_replace("/[0-9]*$/", "", $key);
$newArray[$key] = (isset($newArray[$key])) ? $newArray[$key] + $value : $value;
}
print_r($newArray);

How to implode subarrays in a 2-dimensional array?

I want to implode values in to a comma-separated string if they are an array:
I have the following array:
$my_array = [
"keywords" => "test",
"locationId" => [ 0 => "1", 1 => "2"],
"industries" => "1"
];
To achieve this I have the following code:
foreach ($my_array as &$value)
is_array($value) ? $value = implode(",", $value) : $value;
unset($value);
The above will also change the original array. Is there a more elegant way to create a new array that does the same as the above?
I mean, implode values if they are an array in a single line of code? perhaps array_map()? ...but then I would have to create another function.
Just create a new array and set the elements (-;
<?php
...
$new_array = [];
foreach ($my_array as $key => $value)
$new_array[$key] = is_array($value) ? implode(",", $value) : $value;
Just append values to new array:
$my_array = [
"keywords" => "test",
"locationId" => [ 0 => "1", 1 => "2"],
"industries" => "1",
];
$new_Array = [];
foreach ($my_array as $value) {
$new_Array[] = is_array($value) ? implode(",", $value) : $value;
}
print_r($new_Array);
And something that can be called a "one-liner"
$new_Array = array_reduce($my_array, function($t, $v) { $t[] = is_array($v) ? implode(",", $v) : $v; return $t; }, []);
Now compare both solutions and tell which is more readable.
You don't need to write/iterate a conditional statement if you type the strings (non-arrays) as single-element arrays before imploding them.
With array_map(): (Demo)
$my_array = [
"keywords" => "test",
"locationId" => [ 0 => "1", 1 => "2"],
"industries" => "1"
];
var_export(
array_map(
function($v) {
return implode(',', (array)$v);
},
$my_array
)
);
Or from PHP7.4, array_map() with arrow function syntax: (Demo)
var_export(
array_map(fn($v) => implode(',', (array)$v), $my_array)
);
Or array_walk() and modification by reference (Demo)
array_walk(
$my_array,
function(&$v) {
$v = implode(',', (array)$v);
}
);
var_export($my_array);
Or a foreach loop: (Demo)
foreach ($my_array as &$v) {
$v = implode(',', (array)$v);
}
var_export($my_array);
All snippets will output:
array (
'keywords' => 'test',
'locationId' => '1,2',
'industries' => '1',
)
$arr = array( 'key1' => array( 'one', 'key2' => array( 'two',
'three' ) ), 'four', 'five' );
$finalData = [];
array_walk_recursive(
$arr,
function( $subArr ) use ( &$finalData ) {
$finalData[] = $subArr;
}
);
$str = is_array( $finalData ) ? implode( ",", $finalData ) : $finalData;
print_r( $str ); // one,two,three,four,five

Merge two associative arrays sharing keys and concatenate string values

I have two arrays:
$arr1 = array("123" => "abc");
$arr2 = array("123" => "xyz", "456" => "lmn");
I want the resultant array to be:
$arr = array("123" => "abc,xyz", "456" => "lmn");
I know I can write some code to fetch the values corresponding to keys and then concat with a separator like ';' or ',', but I want to know is there any efficient way to do this?
An in-built function maybe?
Simple foreach will do! Check inline comments
$arr1 = ["123" => "abc"];
$arr2 = ["123" => "xyz", "456" => "lmn"];
foreach ($arr2 as $key => $value) {
if(array_key_exists($key, $arr1)) // Check if key exists in array
$arr1[$key] .= ",$value"; // If so, append
else
$arr1[$key] = $value; // otherwise, add
}
print_r($arr1);
Prints
Array
(
[123] => abc,xyz
[456] => lmn
)
Check this Eval
try this:
$arr1 = array("123" => "abc");
$arr2 = array("123" => "xyz", "456" => "lmn");
$o = [];
foreach($arr1 as $k => $v)
{
$o[$k][] = $v;
}
foreach($arr2 as $k => $v)
{
$o[$k][] = $v;
}
$result = array_map(function($v){implode(',', array_unique($v));}, $o);

Array Difference for multi dimentional array

I have two array
$array1 = array
(
array('A',0),
array('B',0),
array('C',0),
array('D',0),
array('E',0),
array('F',0),
)
$array2 = array
(
array('A',5),
array('B',6),
array('C',10),
array('F',23),
)
$array2 will be changing sometimes A keys is there or its not there. It is applied for all keys.
I want to create a new array or replace the array values in $array1 to
$array1 = array
(
array('A',5),
array('B',6),
array('C',10),
array('D',0),
array('E',0),
array('F',23),
)
Try something like below
if(count($array1) > count($array2)){
$tempArr1 = $array1;
$tempArr2 = $array2;
}else{
$tempArr1 = $array2;
$tempArr2 = $array1;
}
$newArr = array();
foreach($tempArr1 as $values){
$a = $values[0]; $n = $values[1];
foreach($tempArr2 as $key=>$val){
if($val[0] == $a){
$n = ($val[1] > $n) ? $val[1] : $n;
unset($tempArr2[$key]);
}
}
$newArr[] = array($a, $n);
}
print_r($newArr);
$array1 = array (
array('A',0),
array('B',0),
array('C',0),
array('D',0),
array('E',0),
array('F',0),
);
$array2 = array (
array('A',5),
array('B',6),
array('C',10),
array('F',23),
);
foreach( $array2 as $itemKey2 => $itemVal2 ) {
$found = false;
foreach( $array1 as $itemKey1 => $itemVal1 ) {
if( $itemVal1[0] == $itemVal2[0] ) {
$found = true;
$array1[$itemKey1][1] = $itemVal2[1];
break;
}
}
if( !$found )
$array1[] = $item2;
}
echo var_export( $array1, true );
In retrospect, this scenario seems needlessly complicated. Unless something else truly requires this structure, if possible use something like:
$array1 = array (
'A' => 0,
'B' => 0,
'C' => 0,
'D' => 0,
'E' => 0,
'F' => 0
);
$array2 = array (
'A' => 5,
'B' => 6,
'C' => 10,
'F' => 23
);
foreach( $array2 as $key => $val ) {
$array1[$key] = $val;
}

Re-order an array by splitting it in 2 and add the first part to the end

I want to split an array in 2 pieces and add the first slice to the end. The point where it should splitten is set in another variable.
$where = 7;
$array = array( 1 => "aaa", 2 => "bbb", 7 => "ccc", 13 => "ddd", 20 => "eee" );
//...code...
//I'd like to have
$array = array(7 => "ccc", 13 => "ddd", 20 => "eee", 1 => "aaa", 2 => "bbb" );
How to achieve that?
foreach($array as $key=>$value)
{
if ($key === $where)
{
break;
}
unset($array[$key]);
$array[$key] = $value;
}
You can use array_slice() to split the array twice -->
$arr1 = array_slice($array, 0, $where-1);
$arr2 = array_slice($array, $where, count($array)-1);
$array = array();
$array[] = $arr2;
$array[] = $arr1;
function split_array($array, $where) {
$temp_array = array();
foreach ($array as $key => $value) {
if($key != $where) {
$temp_array[$key] = $value;
unset($array[$key]);
}
else {
break;
}
}
//return array_merge($array, $temp_array);
return ($array+$temp_array);
}
You can use array_slice() with a offset to split the array, and join the two chunks with the array union operator.
$where = 7;
$array = array( 1 => "aaa", 2 => "bbb", 7 => "ccc", 13 => "ddd", 20 => "eee" );
$offset = array_search($where, array_keys($array), true);
if ($offset !== false) {
$array = array_slice($array, $offset, null, true) + $array;
}

Categories