PHP Nested Array - Output sub-array contents and array name - php

Consider this nested array:
$link = array(
'Level 1' => array(
'Monthly' => array(
'note' => 'Note 1 1',
'link' => '1.1.com',
),
'6 Month' => array(
'note' => 'Note 1 6',
'link' => '1.6.com',
),
),
'Level 2' => array(
'Monthly' => array(
'note' => 'Note 2.1',
'link' => '2.1.com',
),
'6 Month' => array(
'note' => 'Note 2.6',
'link' => '2.6.com',
),
),
How would I gracefully use a foreach to achieve the following:
if $var = 'Level 1' output
Monthly
6 Month
I'm suspecting I might need to do a loop inside a loop? I can iterate through the array, but am having trouble figuring out how to call the name of the sub-array...

<?php
$key = 'Level 1';
$link = array(
'Level 1' => array(
'Monthly' => array(
'note' => 'Note 1 1',
'link' => '1.1.com',
),
'6 Month' => array(
'note' => 'Note 1 6',
'link' => '1.6.com',
),
),
'Level 2' => array(
'Monthly' => array(
'note' => 'Note 2.1',
'link' => '2.1.com',
),
'6 Month' => array(
'note' => 'Note 2.6',
'link' => '2.6.com',
),
),
);
if(isset($link[$key])) {
foreach($link[$key] as $array) {
print_r($array);
}
}
?>
RETURNS
Array
(
[note] => Note 1 1
[link] => 1.1.com
)
Array
(
[note] => Note 1 6
[link] => 1.6.com
)
I check to see if it is set first and then run a foreach on the set key to print out what you need.
EDIT:
if(isset($link[$key])) {
foreach($link[$key] as $key => $array) {
print $key;
print_r($array);
}
}
Which returns
Monthly
Array
(
[note] => Note 1 1
[link] => 1.1.com
)
6 Month
Array
(
[note] => Note 1 6
[link] => 1.6.com
)

I think using nested loop in this case is graceful.
Just use two foreach.

that's how it'd look like if you're trying to define the arrays within the main array
foreach ($link as $sub_array) {
//do something
foreach ($sub_array as $sub_of_sub) {
// do something and so on
}
}

Related

Replace key in array, with keeping order intact

I would like to replace keys in arrays, because I will move them on two indexes up.
Problem that I am facing is that those are containing same names which will not be ok, if i want to move them up.
This is how array looks like.
$list = array(
'ind' => array(
'messagetype' => 'Alert',
'visibility' => 'Public',
'info' => array(
0 => array(
'urgency' => 'Urgent',
'params' => array(
0 => array(
'Name' => 'display',
'value' => '3; top',
),
1 => array(
'Name' => 'level',
'value' => '1; blue',
),
),
'area' => array(
'ard' => 'Bob',
'code' => array(
0 => array(
'Name' => 'Badge',
'value' => 'GSSD154',
),
),
),
),
1 => array(
'messagetype' => 'Information',
'visibility' => 'Private',
'info' => array(
0 => array(
'urgency' => 'Minor',
'params' => array(
0 => array(
'Name' => 'display',
'value' => '1; left',
),
1 => array(
'Name' => 'level',
'value' => '1; red',
),
),
'area' => array(
'ard' => 'Bob',
'code' => array(
0 => array(
'Name' => 'Badge',
'value' => 'GBECS23',
),
),
),
),
),
),
),
),
);
and this is how I would like the output to be with changing keys in Name0, Name1, which are inside params.
$list = array(
'ind' => array(
'messagetype' => 'Alert',
'visibility' => 'Public',
'info' => array(
0 => array(
'urgency' => 'Urgent',
'params' => array(
0 => array(
'Name0' => 'display',
'value0' => '3; top',
),
1 => array(
'Name1' => 'level',
'value1' => '1; blue',
),
),
'area' => array(
'ard' => 'Bob',
'code' => array(
0 => array(
'Name' => 'Badge',
'value' => 'GSSD154',
),
),
),
),
1 => array(
'messagetype' => 'Information',
'visibility' => 'Private',
'info' => array(
0 => array(
'urgency' => 'Minor',
'params' => array(
0 => array(
'Name0' => 'display',
'value0' => '1; left',
),
1 => array(
'Name1' => 'level',
'value1' => '1; red',
),
),
'area' => array(
'ard' => 'Bob',
'code' => array(
0 => array(
'Name' => 'Badge',
'value' => 'GBECS23',
),
),
),
),
),
),
),
),
);
I have tried with a lots of examples over this website, but could not find one to achieve this.
Code that I used from
How to replace key in multidimensional array and maintain order
function replaceKey($subject, $newKey, $oldKey) {
// if the value is not an array, then you have reached the deepest
// point of the branch, so return the value
if (!is_array($subject)) {
return $subject;
}
$newArray = array(); // empty array to hold copy of subject
foreach ($subject as $key => $value) {
// replace the key with the new key only if it is the old key
$key = ($key === $oldKey) ? $newKey : $key;
// add the value with the recursive call
$newArray[$key] = replaceKey($value, $newKey, $oldKey);
}
return $newArray;
}
$s = replaceKey($list, 'Name0', 'Name');
print "<PRE>";
print_r($s);
at the moment I get this output:
[0] => Array
(
[Name0] => display
[value] => 1; left
)
[1] => Array
(
[Name0] => level
[value] => 1; red
)
any help would be appreciated. regards
A very strange question, but why not?
The following function returns nothing (a procedure) and changes the array in-place using references but feel free to rewrite it as a "real" function (without references and with a return statement somewhere).
The idea consists to search for arrays, with numeric keys and at least 2 items, in which each item has the Name and value keys. In other words, this approach doesn't care about paths where the targets are supposed to be:
function replaceKeys(&$arr) {
foreach ($arr as &$v) {
if ( !is_array($v) )
continue;
$keys = array_keys($v);
if ( count($keys) < 2 ||
$keys !== array_flip($keys) ||
array_keys(array_merge(...$v)) !== ['Name', 'value'] ) {
replaceKeys($v);
continue;
}
foreach ($v as $k => &$item) {
$item = array_combine(["Name$k", "value$k"], $item);
}
}
}
replaceKeys($list);
print_r($list);
demo

Remove Child Array If Value of A Key is Duplicate

I want to remove a child array from a multi-dimensional array in case a duplicate value found for a particular key. The answer(s) here didn't work at all. The answer here works, however, for large amount of arrays, that gets pretty slower. Looking for a cleaner and faster solution.
Example PHP Array
$args = array();
$args[] = array(
'section' => array(
'id' => 'section1',
'name' => 'Section 1',
),
'name' => 'Shortcode Name',
'action' => 'shortcodeaction',
'icon' => 'codeicon',
'image' => 'codeimage',
);
$args[] = array(
'section' => array(
'id' => 'section2',
'name' => 'Section 2',
),
'name' => 'Shortcode2 Name',
'action' => 'shortcodeaction2',
'icon' => 'codeicon2',
'image' => 'codeimage2',
);
$args[] = array(
'section' => array(
'id' => 'section3',
'name' => 'Section 3',
),
'name' => 'Shortcode3 Name',
'action' => 'shortcodeaction3',
'icon' => 'codeicon3',
'image' => 'codeimage3',
);
$args[] = array(
'section' => array(
'id' => 'section1',
'name' => 'Section 4',
),
'name' => 'Shortcode4 Name',
'action' => 'shortcodeaction4',
'icon' => 'codeicon4',
'image' => 'codeimage4',
);
$args[] = array(
'section' => array(
'id' => 'section5',
'name' => 'Section 5',
),
'name' => 'Shortcode5 Name',
'action' => 'shortcodeaction5',
'icon' => 'codeicon5',
'image' => 'codeimage5',
);
$sections = array();
foreach ( $args as $arg ) {
$sections[] = $arg['section'];
}
And, the print_r($sections) result.
Array
(
[0] => Array
(
[id] => section1
[name] => Section 1
)
[1] => Array
(
[id] => section2
[name] => Section 2
)
[2] => Array
(
[id] => section3
[name] => Section 3
)
[3] => Array
(
[id] => section1
[name] => Section 4
)
[4] => Array
(
[id] => section5
[name] => Section 5
)
)
Both Array[0] and Array[3] has the same value for the key id, therefor the entire Array[3] has to be removed in my case to avoid duplicates.
This is working for me though, but it gets really slow when there are 100s or more arrays.
$knownIds = array();
foreach( $sections AS $key=>$item ) {
if( array_key_exists($item['id'], $knownIds) === true ) {
unset( $sections[$key] );
} else {
$knownIds[$item['id']] = $key;
}
}
$sections = array_values($sections);
Tried several answers here in StackOverflow (including this), but none of them helped in my case.
Thanks
You can modify the whole using array_column and array_filter -
//get all the sections value
$section = array_column($args, 'section');
//store ids in temp array
$idArray = array_unique(array_column($section, 'id'));
//filter the array having unique id
$uniqueSections = array_filter($section, function ($key, $value) use ($idArray) {
return in_array($value, array_keys($idArray));
}, ARRAY_FILTER_USE_BOTH);
var_dump($uniqueSections);
For PHP <5.5
$section = array_map(function($args) {
return $args['section'];
}, $args);
$idArray = array_unique(array_map(function($section){return $section['id'];}, $section));

PHP split array by key

I have an array which looks like this:
array (
'id' => 1,
'channel_id' => 1,
'field_group' => 1,
'url_title' => 'the_very_first_entry',
'title' => 'The Very First Entry',
'fields' =>
array (
0 =>
array (
'label' => 'Enter Item Name:',
'type' => 'text',
'channel_data_id' => 1,
'value' => 'Item one',
'field_id' => 1
),
1 =>
array (
'label' => 'Enter Item Description',
'type' => 'textarea',
'channel_data_id' => 2,
'value' => 'Some long text blah blah',
'field_id' => 2
)
)
)
I want to split this into 2 arrays, one containing the fields, and the other containing everything else, ie.
Array 1:
array (
'id' => 1,
'channel_id' => 1,
'field_group' => 1,
'url_title' => 'the_very_first_entry',
'title' => 'The Very First Entry'
);
Array 2:
array (
0 =>
array (
'label' => 'Enter Item Name:',
'type' => 'text',
'channel_data_id' => 1,
'value' => 'Item one',
'field_id' => 1
),
1 =>
array (
'label' => 'Enter Item Description',
'type' => 'textarea',
'channel_data_id' => 2,
'value' => 'Some long text blah blah',
'field_id' => 2
)
)
Is there a better solution that iterating through the original array with a foreach loop?
Is there a better solution that iterating through the original array with a foreach loop
You know the split-key so there's no real use for foreach:
$src = array(...); // your source array
$fields_array = $src['fields'];
unset($src['fields']);
If I understood your question correct.
<?php
$base = array(...); // your array
// array values
$baseArrays = array_filter($base, function($item){
return is_array($item);
});
// not array values
$not = array_diff($base, $baseArrays);
As an alternative solution, if the fields key is always the last element of the array, you can use array_pop.
$fields = array_pop($array);
And that's it. Demo.

Extracting data from complicated associative array in php and put into new array

I have an complicated array that looks like this:
$input=array(
(int) 0 => array(
'XXX' => array(
'id' => '7',
'p_id' => '1',
'address' => '9463',
'arrival_time' => '2014-05-01 03:30:00'
),
'YYY' => array(
'id' => '1',
'iden' => '1111',
'name' => 'Tom'
)
),
(int) 1 => array(
'XXX' => array(
'id' => '9',
'p_id' => '2',
'address' => '9469',
'arrival_time' => '2014-05-27 16:43:58'
),
'YYY' => array(
'id' => '2',
'iden' => '2222',
'name' => 'Sam'
)
),
(int) 2 => array(
'XXX' => array(
'id' => '3',
'p_id' => '3',
'address' => '9462',
'arrival_time' => '2014-04-21 14:05:00'
),
'YYY' => array(
'id' => '3',
'iden' => '3333',
'name' => 'James'
)
)
)
I would like to convert it such that it looks like this;
$output=array(
(int) 0 => array(
'name' => 'Tom',
'iden' => '1111',
'address' => '9463'
),
(int) 1 => array(
'name' => 'Sam',
'iden' => '2222',
'address' => '9469'
),
(int) 2 => array(
'name' => 'James',
'iden' => '3333',
'address' => '9462'
)
I wrote some code to solve this problem:
foreach ( $input as $key => $value)
{
$output['name']=$input[$key]['YYY']['name'];
$output['iden']=$input[$key]['YYY']['iden'];
$output['address']=$input[$key]['XXX']['address'];
}
Unfortunately, it retrieves only the last element of the input array.
Can someone more experienced help?
Thank you very much.
You are overwriting the values in each iteration, as you always write to $output['name'] etc.
foreach ( $input as $key => $value)
{
$output[$key] = array(
'name' => $value['YYY']['name'],
'iden' => $value['YYY']['iden'],
'address' => $value['XXX']['address']
);
}
The key here is using $output[$key] instead of $output - this way you will add a new element in each iteration.
Also $input[$key] and $value are equivalent, so I used the shorter variant ;)
Try this in your foreach loop :-
foreach ( $input as $key=>$value)
{
$output[$key]['name']=$value['YYY']['name'];
$output[$key]['iden']=$value['YYY']['iden'];
$output[$key]['address']=$value['XXX']['address'];
}
You have to add an index to the array in the foreach: $output[$key]["name"] = ...;

PHP multidimensional array handling - looking up a value 2 arrays deep

I'm having a bit of trouble accessing data within an array that looks like the following:
array (
0 => array ( 'value' => '46', 'label' => 'Brand A', ),
1 => array ( 'value' => '45', 'label' => 'Brand B', ),
2 => array ( 'value' => '570', 'label' => 'Brand C', ),
);
Essentially I want to be able to return the contents of the label when given the value (e.g. 45 returns Brand B), but am not sure how to do this within these levels.
Do I need to break this array down into smaller chunks through a loop of some sort to access this data?
Thanks
When creating the array you need to use the value as the key:
array(
'46' => 'Brand A',
'45' => 'Brand B',
);
OR
$arrayVar['46'] = 'Brand A';
etc.
If you aren't the one creating the array, then you can foreach loop through it and rework it into a different structure.
<?php
$arr = array (
0 => array ( 'value' => '46', 'label' => 'Brand A', ),
1 => array ( 'value' => '45', 'label' => 'Brand B', ),
2 => array ( 'value' => '570', 'label' => 'Brand C', ),
);
$val = 45; // search for 45
foreach($arr as $vals){
if($vals['value'] == $val){
echo "value=".$vals['value'];
echo "<br>";
echo "label=".$vals['label'];
}
}
?>
Try this
<?php
$arr = array (
0 => array ( 'value' => '46', 'label' => 'Brand A', ),
1 => array ( 'value' => '45', 'label' => 'Brand B', ),
2 => array ( 'value' => '570', 'label' => 'Brand C', ),
);
foreach($arr as $ele){
echo "value=".$ele['value']." and label=".$ele['label'];
}
?>

Categories