Flatten a multi-dimensional array, whilst removing an element from each - php

Is it possible to flatten a multi-dimensional array, whilst also removing an element from each sub-array?
Currently, I am storing two elements per sub-array, like so:
Array (
[billing_first_name] => Array (
[0] => Test
[1] => 1
)
[billing_last_name] => Array (
[0] => Test
[1] => 1
)
)
But I need to remove the second sub-element, flattening the array to:
Array (
[billing_first_name] => Test
[billing_last_name] => Test
)
I had thought that this could be possible through a foreach, but after removing the 2nd element from the sub-array, I'm unsure what route would be most efficient to flatten the array.
foreach( $customer_data_new as $key => $value ) {
unset($customer_data_new[$key][1]);
}
If anyone could explain the best option, I would be graatful.

Can you try the below code
$customer_data_new = array(
'billing_first_name' => array(
'0' =>'Test',
'1' => 1
),
'billing_last_name' => array(
'0' =>'Test',
'1' => 1
)
);
$newData = array();
foreach( $customer_data_new as $key => $value ) {
$newData[$key] = $value[0];
}
print_r($newData);
Demo Link

Call current() on every subarray. Dead simple.
Code: (Demo)
var_export(array_map('current', $customer_data_new));
Output:
array (
'billing_first_name' => 'Test',
'billing_last_name' => 'Test',
)

Related

Simplify a multidimensional array in PHP

I've received and XML, converted it into an array for usage.
The XML comes in unpredictable multi dimension when I convert it into array.
Had been looking around but could not find a suitable solution.
An alternative is to simplify the converted array.
I've converted an XML to array in PHP, and the result looked like this:
Array
(
[GetMLCBRes] => Array
(
[0] => Array
(
[Ord] => Array
(
[0] => Array
(
[OrdId] => Array
(
[0] => DP Order ID
)
)
)
[ReqInf] => Array
(
[0] => Array
(
[ReqDat] => Array
(
[0] => Date of Request
)
)
)
[Res] => Array
(
[0] => PDF Report
)
)
)
)
May I know how to drop the index like [0] but remain the assoc keys like [Ord], [OrdId], [ReqInf] and [Res], etc.
How to convert it to become like this?
Array
(
[GetMLCBRes] => Array
(
[Ord] => Array
(
[OrdId] => DP Order ID
)
[ReqInf] => Array
(
[ReqDat] => Date of Request
)
[Res] => PDF Report
)
)
it works but if you change your structure maybe it won't. It's not optimized too :)
$input = Array(
'GetMLCBRes' => Array(Array(
'Ord' => Array(Array(
'OrdId' => Array('DP Order ID')
)),
'ReqInf' => Array(Array(
'ReqDat' => Array('Date of Request')
)),
'Res' => Array('PDF Report')
))
);
foreach($input as &$in){
$sub = $in[0];
foreach($sub as $key => &$value){
$sub2 = $value[0];
if(!is_array($sub2)){
$sub[$key] = $sub2;
continue;
}
$final2 = array();
foreach($sub2 as $key2 => $final)
$final2[$key2] = $final[0];
$sub[$key] = $final2;
}
$in = $sub;
}
var_dump($input);
You can test it here : http://sandbox.onlinephpfunctions.com/code/a6770c7649d7d277aa1dc3544093cc87bed0951d
This should work as expected :
function recursive_skip(array $ary) {
foreach($ary as $k => &$v) {
if (is_array($v)) {
// Skip it
$v = $v[0];
}
if (is_array($v)) {
// If current array item is an array itself, recursively call the function on it
$v = recursive_skip($v);
}
}
// Return updated array to calling context
return $ary;
}
$source = Array(
'GetMLCBRes' => Array(Array(
'Ord' => Array(Array(
'OrdId' => Array('DP Order ID')
)),
'ReqInf' => Array(Array(
'ReqDat' => Array('Date of Request')
)),
'Res' => Array('PDF Report')
))
);
$dest = recursive_skip($source);
var_dump($dest);
A few caveats : the function will only skip one array level each time (but could be adapted to handle more if needed) and might come with a significant performance cost if your source array is huge since it's recursive (O(n)), it just walks through the whole array tree.

2 arrays: keep only elements with different value

I have 2 arrays:
Array
(
[0] => Array
(
[id] => 1
[fieldname] => banana
[value] => yellow
)
)
Array
(
[0] => Array
(
[id] => 1
[fieldname] => rome
[value] => city
)
[1] => Array
(
[id] => 2
[fieldname] => bla
[value] => yes
)
)
I want to create a new array that contains only elements where "id" is different. In other words I want to get this output:
Array
(
[0] => Array
(
[id] => 2
[fieldname] => bla
[value] => yes
)
)
[id] => 2 was the only different [id] so I keep it.
Said that I've already managed to achieve my goal with an inefficient pile of foreach, if statements and temp variables. I really don't want to use a wall of code for this very small thing so I started to look for a native PHP function with no success. What's the easiest way to get the result? Is it possible that I strictly need to use a foreach with so many if?
You can use array_udiff with a function.
Computes the difference of arrays by using a callback function for
data comparison.
Returns an array containing all the values of the first array that are not
present in any of the other arguments.
The code:
// Setup two arrays as per your question
$array1 = array (
'0' => array (
'id' => '1',
'fieldname' => 'banana',
'value' => 'yellow',
)
);
$array2 = array (
'0' => array (
'id' => '1',
'fieldname' => 'rome',
'value' => 'city',
),
'1' => array (
'id' => '2',
'fieldname' => 'bla',
'value' => 'yes',
)
);
// Setup the callback comparison function
function arrayCompare($array2, $array1) {
return $array2['id'] - $array1['id'];
}
// Use array_udiff() with the two arrays and the callback function
$arrayDiff = array_udiff($array2, $array1, 'arrayCompare');
print_r($arrayDiff);
The above code returns the following:
Array (
[1] => Array (
[id] => 2
[fieldname] => bla
[value] => yes
)
)
This should do it. Not super short and it does use a temporary variable, so perhaps not what you were looking for. I've named the two arrays one and two.
$ids = array();
$result = array();
foreach ($one as $x) {
$ids[$x['id']] = 1; //This way, isset($x['id']) vill return true
}
foreach ($two as $x) {
if (!isset($ids[$x['id']])) {
$result[] = $x;
}
}
I would be surprised if there wasn't an even more compact way to do it.
EDIT: This is an alternative variant with nested for each. Not particularly short either.
$result = array();
foreach ($one as $x) {
foreach ($two as $y) {
if ($x['id'] == $y['id']) {
//A match, lets try the next $x
continue 2;
}
}
//No matching id in $two
$result[] = $x;
}

array flip collision issue

Is there a function/method I am unaware of that avoids removal of like keys when the array is flipped. Example below:
Original array:
Array ( [last_modified] => input [published] => input [project_content] => textarea )
With array flip (collision of keys):
Array ( [input] => published [textarea] => project_content )
If you want to preserve your keys, you can have a two dimensional array:
<?php
$arr = array ( 'last_modified' => 'input', 'published' => 'input', 'project_content' => 'textarea' );
$result = array();
foreach($arr as $k => $v) {
if (array_key_exists($v, $result)) {
$result[$v][] = $k;
} else {
$result[$v] = array($k);
}
}
print_r($result);
?>
This will print out:
Array
(
[input] => Array
(
[0] => last_modified
[1] => published
)
[textarea] => Array
(
[0] => project_content
)
)
There is a dead simple way to get all the keys in the array that have the value "input" using the standard function array_keys:
$keys = array_keys($array, "input");
That is all; see it in action.

populate php multidimenssional array with foreach loop

I need to create an array like the following:
$va_body=array(
"bundles" => array(
"$table.$elem" => array("convertCodesToDisplayText" => true),
"$table.$elem" => array("convertCodesToDisplayText" => true),
)
);
$table is a string that does not change and $elem is extracted from an array.
I got close with the following code, but it ends up with only the last value from $bund, $bund is an array with two values. I guess the array is redeclared in each loop?
$va_body=array(); // declare the array outside the loop
foreach ($bund as $elem ) {
$va_body['bundles'] = array($table.".".$elem=>array("convertCodesToDisplayText" => true));
}
$bund array has two elements "description" and "type_id".
$va_body['bundles'][] // Adding [] doesn't work as it modifies the expected outcome.
print_r($va_body) looks like this:
Array (
[bundles] => Array (
[ca_objects.type_id] => Array (
[convertCodesToDisplayText] => 1
)
)
)
I need it to be:
Array (
[bundles] => Array (
[ca_objects.description] => Array (
[convertCodesToDisplayText] => 1
)
[ca_objects.type_id] => Array (
[convertCodesToDisplayText] => 1
)
)
)
Thanks in advance.
#phpisuber01
Using:
$va_body['bundles'][] = array($table.".".$elem=>array("convertCodesToDisplayText" => true));
print_r($va_body); looks like this:
Array (
[bundles] => Array (
[0] => Array (
[ca_objects.description] => Array (
[convertCodesToDisplayText] => 1
)
)
[1] => Array (
[ca_objects.type_id] => Array (
[convertCodesToDisplayText] => 1
)
)
)
)
And I need it to be like this:
Array (
[bundles] => Array (
[ca_objects.description] => Array (
[convertCodesToDisplayText] => 1
)
[ca_objects.type_id] => Array (
[convertCodesToDisplayText] => 1
)
)
)
Answer by #phpisuber01:
$va_body['bundles'][$table.".".$elem] = array("convertCodesToDisplayText" => true);
Thank you very much!
You need to make an array of arrays. In your loop change the following line:
$va_body['bundles'][$table.".".$elem] = array("convertCodesToDisplayText" => true);
Added [] after $va_body['bundles'].
All this does is keep adding the new bundles into the array. Your original code is overwriting bundles each iteration. That's why you only get the last one.
Updated to get closer to OP's exact needs.
$va_body = array();
$va_body['bundles'] = array();
foreach ($bund AS $elem)
{
$va_body['bundles']["{$table}.{$elem}"] = array("convertCodesToDisplayText" => true);
}

PHP dealing with arrays

Array
(
[0] => Array
(
[uid] => 43543534
)
)
I'm trying to get output as [0] => [43543534]
I tried foreach() but I'm getting string as output
Update How do i find max value now in this?
Why don't you have only 1 dimensional array array('0' => 43543534), if you have only 'uid' in the second one
foreach ($yourArray as $key => $val) {
echo '['.$key.'] => ['.$val['uid'].']<br />';
}
$var = array( '0' => array ( 'uid' => '43543534' ) );
foreach($var as $arr):
echo $arr['uid'];
endforeach;
Your question is very unclear, but here are two ways to accomplish that using the original array:
$array = array( '0' => array ( 'uid' => '43543534' ) );
$result[0] = $array[0]['uid];
or with foreach
$array = array( '0' => array ( 'uid' => '43543534' ) );
foreach($array as $a){
$result[] = $a['uid'];
}

Categories