I have data that looks like this:
1 Root Catalog
1/2 Main Website
1/2/4 Cold Beverages
1/2/4/19 Pop - Canned
1/2/4/20 Pop - Natural Low Calorie
1/2/4/21 Pop - Bottled - Large Plastic
1/2/4/22 Pop - Bottled - Small Plastic
And need to turn it into an array that looks like:
array(
1 => array(
'name' => 'Root Catalog',
2 => array(
'name' => 'Main Website',
4 => array(
'name' => 'Cold Beverages',
19 => array(
'name' => 'Pop - Canned'
)
/*more numbers here*/
)
)
)
)
I can't figure out how to assign the array to the parent array while maintaining data integrity.
The issue I'm encountering is that I can have between 1-n levels nested. I've tried exploding the string and reconstructing it using recursion, but it never turns out right. Any idea's I could try?
edit: Best Attempt so far:
foreach ($categories as $category) {
$paths = explode('/', $category->getPath());
$paths = array_reverse($paths);
$temp = array('name' => $category->getName());
foreach ($paths as $key => $value) {
$temp = array($value => $temp);
}
$data = array_merge($data, $temp);
}
$data = array(
'1' => 'Root Catalog',
'1/2' => 'Main Website',
'1/2/4' => 'Cold Beverages',
'1/2/4/19' => 'Pop - Canned',
'1/2/4/20' => 'Pop - Natural Low Calorie',
'1/2/4/21' => 'Pop - Bottled - Large Plastic',
'1/2/4/22' => 'Pop - Bottled - Small Plastic'
);
$out = array();
foreach($data as $route => $value) // take every element of $data
{
$path = explode('/', $route); // split the route into elements
$current = &$out; // get pointer to the root of the output array
foreach($path as $level) // traverse through the path
{
if (!isset($current[$level])) // if branch does not exist, create it
$current[$level] = array();
$current = &$current[$level]; // set current pointer to that branch
}
$current['name'] = $value; // set leaf at the end of the branch
}
print_r($out); // output result
Result:
Array
(
[1] => Array
(
[name] => Root Catalog
[2] => Array
(
[name] => Main Website
[4] => Array
(
[name] => Cold Beverages
[19] => Array
(
[name] => Pop - Canned
)
[20] => Array
(
[name] => Pop - Natural Low Calorie
)
[21] => Array
(
[name] => Pop - Bottled - Large Plastic
)
[22] => Array
(
[name] => Pop - Bottled - Small Plastic
)
)
)
)
)
Related
foreach this array result and echo the results
Array
(
[0] => Array
(
[0] => Array
(
[blog_title] => sooraj bloging
[blog_id] => 2
)
[1] => Array
(
[blog_title] => What are Mobile App Testing Challenges?
[blog_id] => 4
)
[2] => Array
(
[blog_title] => sooraj blog
[blog_id] => 8
)
)
[1] => Array
(
[0] => Array
(
[title] => sooraj casestudy
)
)
[2] => Array
(
[0] => Array
(
[career_id] => 14
[title] => Software Engineer .NET sooraj
[location] => Kochi, India.
[description] => Developing .NET applications.
[qualification] => B.Tech. in CSE, MCA
[status] => 0
[created_at] => 2017-11-20 13:14:29
[updated_at] => 0000-00-00 00:00:00
)
)
[3] => Array
(
)
[4] => Array
(
[0] => Array
(
[tst_id] => 146
[tst_name] => John Kasha
[tst_quote] => Gadgeon was extremely professional and was easy to commun sooraj icate and work with on a day-to-day basis. I also liked the fact that they were willing to do the research for specific tasks and present a viable solution or workaround to keep the project on schedule. I would recommend them for any task for any industry software or hardware. Bottom line, they get it done and you get results, not excuses. VP of Engineering.
[tst_desig] => Vice President,Product Development and Engineering
[tst_image] => 91c09ac9ee6234fdfcc523a393800bd5.jpg
[url] =>
[crop_name] => 668959f965ab28815dc97bbc1f8718d8.jpg
[sysDate] => 2017-11-20 15:42:34
)
)
)
Just Run this code
<?php
$array = array(
array(
array(
'blog_title' => 'sooraj bloging',
'blog_id' => 2
),
array(
'blog_title' => 'What are Mobile App Testing Challenges?',
'blog_id' => 4
),
array(
'blog_title' => 'sooraj blog',
'blog_id' => 8
)
),
array(
array(
'title' => 'sooraj casestudy',
)
),
array(
array(
'career_id' => 14,
'title' => 'Software Engineer .NET sooraj',
'location' => 'Kochi, India.',
'description' => 'Developing .NET applications.',
'qualification' => 'B.Tech. in CSE, MCA',
'status' => 0,
'created_at' => '2017-11-20 13:14:29',
'updated_at' => '0000-00-00 00:00:00'
)
),
array(),
array(
array(
'tst_id' => 146,
'tst_name' => 'John Kasha',
'tst_quote' => 'Gadgeon was extremely professional and was easy to commun sooraj icate and work with on a day-to-day basis. I also liked the fact that they were willing to do the research for specific tasks and present a viable solution or workaround to keep the project on schedule. I would recommend them for any task for any industry software or hardware. Bottom line, they get it done and you get results, not excuses. VP of Engineering.',
'tst_desig' => 'Vice President,Product Development and Engineering',
'tst_image' => '91c09ac9ee6234fdfcc523a393800bd5.jpg',
'url' => '',
'crop_name' => '668959f965ab28815dc97bbc1f8718d8.jpg',
'sysDate' => '2017-11-20 15:42:34'
)
)
);
foreach ($array as $value){
foreach ($value as $row){
foreach ($row as $key=> $row1){
echo $key.' - '. $row1;
}
echo '<br>';
}
}
?>
Depending what you're trying to do (debugging vs tabular display), you can "pretty print" the array with var_export like so:
// Assuming your array is $data
echo '<pre>'.var_export($data, TRUE).'</pre>';
Otherwise, to loop through the array as is with a foreach:
// Assuming your array is $data
foreach ($data as $subdata) {
// You probably want to check that this is an array for case #3
if(is_array($subdata)) {
foreach ($subdata as $valueset) {
// Check for array validity (not required for example data, but good to be safe)
if (is_array($valueset)) {
foreach ($subdata as $key => $value) {
// Print each key, value pair as a row
echo $key .' => '.$value . '<br />';
}
}
}
} else {
// Optional handling of empty set
echo 'No data to display...';
}
}
foreach ($array as $value){
foreach ($value as $row){
if (is_array($row)){
foreach ($row as $key => $val){
echo $key."=>". $val."<br>";
}///endForeach
}///endIf
else {
echo $row;
}////endElse
}
}
I have the following array:
Array
(
[0] => Array
(
[name] => bss2
[label] => front
[text] => just a testing item
)
[1] => Array
(
[name] => bss3
[label] => front top
[text] => front top testing item
)
[2] => Array
(
[name] => J334
[label] => back top
[text] => masking test back top
)
[3] => Array
(
[name] => J3366
[label] => back
[text] => back non mask test
)
)
What i would like to accomplish is to check to see if label = front then group the ones with front together and same with back all in one big array to have it looks like so:
[approval] => Array(
[0] => Array(
[name] => front
[prev] => Array(
[0]=>Array(
[name] => bss2
)
[1]=>Array(
[name] => bss2
)
)
)
[1] => Array(
[name] => back
[prev] => Array(
[0]=>Array(
[name] => J334
)
[1]=>Array(
[name] => J3366
)
)
)
)
so far I dont have much and am stuck but this is my code
foreach($info as $data) {
if(strtolower(strpos($data['label'], "front") !==false)) {
} else {
}
}
Iv also tried using array_chunk which works great but what would happen if there are 3 elements that need to be grouped or 4
array_chunk($info, 2);
or what would happen if the order is different where one is front and second is back it will then combine the front and back together.
Any help is greatly appreciated thank you.
This should do it, assuming the only choices are front and back.
$result = array(array('name' => 'front', 'prev' => array()),
array('name' => 'back', 'prev' => array()));
foreach ($info as $data) {
$i = (strpos(strtolower($data['label']), "front") !== false)
$result[$i]['prev'][] = array('name' => $data['name'];
}
$newinfo = array('approval' => $result;
It's not clear to me exactly what you're after... If it's just front and back or if you want top and any other group as well?
Methods
Anyway, here are a few options that should cover most cases.
Front and Back only
This is the simplest and will just check for front and back. If it finds them then it will ad to front and back in $newArray as is required.
$newArray = array(array('front'), array('back')); //The new reformatted array
for($i = 0; $i < count($initialArray); $i++){
if(strpos($initialArray[$i]['label'], 'front') !== FALSE){//Check if group is front
$newArray[0]['prev'][] = array('name'=>$initialArray[$i]['name']); //Add to front
}
if(strpos($initialArray[$i]['label'], 'back') !== FALSE){//Check if group is back
$newArray[1]['prev'][] = array('name'=>$initialArray[$i]['name']); //Add to back
}
}
Pre-defined groups
This one's a bit more complex and will search for all groups found in $groups. The code below shows only front and back but you could also add in, for example, top or any others.
$groups = array('front', 'back'); //Groups to search for e.g. front, back, and top
$newArray = array(); //The new reformatted array
for($i = 0; $i < count($initialArray); $i++){
foreach($groups as $group){
if(strpos($initialArray[$i]['label'], $group) !== FALSE){//Check if group is in label
$groupKey = array_search($group, $groups); //Search for the key in $groups
$newArray[$groupKey]['prev'][] = array('name'=>$initialArray[$i]['name']); //Add to relevant group
}
}
}
Automated
This is the most advanced code which will automatically search and add new groups as they are found in the array. It's also fully automated so all you have to do is point it at the correct array.
$groups = array(); //Index of groups like: top, front, and back
$newArray = array(); //The new reformatted array
for($i = 0; $i < count($initialArray); $i++){
$possibleGroups = explode(' ', strtolower($initialArray[$i]['label'])); //Get list of applicable groups
foreach($possibleGroups as $newGroup){
if(!in_array($newGroup, $groups)){ //If group doesn't already exist in $groups add it
$groups[] = $newGroup;
$newArray[] = array('name'=>$newGroup, 'prev'=>array());
}
$groupKey = array_search($newGroup, $groups); //Search for the key in $groups
$newArray[$groupKey]['prev'][] = array('name'=>$initialArray[$i]['name']); //Add to relevant group
}
}
Test array
The above codes have been tested with the following array...
$initialArray = array(
array(
'name' =>'bss2',
'label'=>'front',
'text' =>'sometihng...'
),
array(
'name' =>'bss3',
'label'=>'front top',
'text' =>'sometihng...'
),
array(
'name' =>'j334',
'label'=>'back top',
'text' =>'sometihng...'
),
array(
'name' =>'j3366',
'label'=>'back',
'text' =>'sometihng...'
)
);
Example Output
Output of the third method (automated) using the test array above.
array (
0 =>
array (
'name' => 'front',
'prev' =>
array (
0 =>
array (
'name' => 'bss2',
),
1 =>
array (
'name' => 'bss3',
),
),
),
1 =>
array (
'name' => 'top',
'prev' =>
array (
0 =>
array (
'name' => 'bss3',
),
1 =>
array (
'name' => 'j334',
),
),
),
2 =>
array (
'name' => 'back',
'prev' =>
array (
0 =>
array (
'name' => 'j334',
),
1 =>
array (
'name' => 'j3366',
),
),
),
)
I am trying to resolve how to clean up my array and my output should be:
1) all numerical indexed and
2) no duplicate values.
This is a sampling of my current array output:
NOTE: index [3]. I am parsing those values into a new array and do not need either of them. They are merged onto the array below as you can see.
Ultimately I am preparing this for .csv format, but I need my array in some type of sequence in order to keep the data in proper presentation form.
Array // print_r();
(
[0] => 3350
[id] => 3350
[1] => Williamson New England Electric
[company] => Williamson New England Electric
[2] => bob#jojozzz.go
[email] => bob#jojozzz.go
[3] => Pumps & Motors,Electronic Systems,Electrical Supply,Electrical
[industry] => Pumps & Motors,Electronic Systems,Electrical Supply,Electrical
[4] => Pumps & Motors
[5] => Electronic Systems
[6] => Electrical Supply
[7] => Electrical
)
This is what I am trying to achieve:
Array
(
[0] => 3350
[1] => Williamson New England Electric
[2] => bob#jojozzz.go
[4] => Pumps & Motors
[5] => Electronic Systems
[6] => Electrical Supply
[7] => Electrical
)
As I said in my comment, it's probably easier to get the array as numerical array from the beginning, if you get it from a MySQL database:
$row = mysql_fetch_row($result);
Then you can do the following to split the value of the last column:
array_splice($row, -1, 1, explode(',', end($row)));
DEMO
See Felix's comment for a possible way to get your array in the right format at source. If thats not possible, this will do the trick;
$array = Array(
'0' => 3350,
'id' => 3350,
'1' => 'Williamson New England Electric',
'company' => 'Williamson New England Electric',
'2' => 'bob#jojozzz.go',
'email' => 'bob#jojozzz.go',
'3' => 'Pumps & Motors,Electronic Systems,Electrical Supply,Electrical ',
'industry' => 'Pumps & Motors,Electronic Systems,Electrical Supply,Electrical ',
'4' => 'Pumps & Motors',
'5' => 'Electronic Systems',
'6' => 'Electrical Supply',
'7' => 'Electrical'
);
$outputArray = array_values( $array );
$uniqueArray = array_unique( $outputArray );
var_dump( $uniqueArray );
Cannot guarantee anything about performance, but you can use is_numeric to ensure (#1) only numerical indexes, and use array_unique to ensure (#2) no duplicates:
$b = filterNonNumericKeysInArray($a);
$b = array_unique($b);
function filterNonNumericKeysInArray($arr) {
$finalArr = Array();
foreach ($arr as $key => $val) {
if (!is_numeric($key)) { continue; }
$finalArr[$key] = $val;
}
return $finalArr;
}
I have a nested array and I wanted to know if there is a way to slip it, so having the nested arrays as individual arrays
Array
(
[0] => Array
(
[menu] => Array
(
[pizza] => Array
(
[Tomato & Cheese] => Array
(
[small] => 5.50
[large] => 9.75
)
[Olives] => Array
(
[small] => 6.85
[large] => 10.85
)
)
[Speciality Pizzas] => Array
(
[Our Special] => Array
(
[ingredients] => Array
(
[0] => Tomatoes
[1] => Olives
[2] => Spinach
[3] => Fresh Garlic
[4] => Mozzarella & Feta Cheese
) --- theres more but you get the idea
Now I want to may a new array with all the pizzas, but without knowing the name "pizza"
at the moment I can do this:
$array = array(json_decode($json, true));
$pizzas = (array)$array[0]['menu']['pizza']
But if the menu changes content (but not structure) and if the 'pizza' changes to 'salads' the above would fail. Is the a way to create the above pizzas array without the name
Thanks
$array = array(json_decode($json, true));
$menu = (array)$array[0]['menu'];
foreach($menu as $item => $item_Data){
//$item might be pizza for example
//$item_Data might be Olives or Our special. Now you have to consider what to do with this. Maybe next foreach loop ?
}
Right now your array has parallel sections for related data. How about if you did something like:
$food_choices = array(
'pizza' => array(
'Tomato & Cheese' => array(
'type' => 'regular',
'prices' => array(...),
'ingredients' => array(...)
),
'Our Special' => array(
'type' => 'specialty',
'prices' => array(...),
'ingredients' => array(...)
),
),
'salads' => array(
'Caesar' => array(...);
'Tossed' => array(...);
)
)
where all the information related to any one menu item as all in the same branch of the meu tree. Then to access any one pizza's information is as simple as:
$data = $food_choices['pizza']['Tomato & Cheese'];
echo 'The large of this pizza costs $', $data['prices']['large'];
echo 'The small Caesar salad contains ', implode($food_choices['salad']['Caesar']['ingredients);
A series of foreach loops might do, even though I don't know what you're doing.
<?php
$pizza = '';
foreach ($array as $food) {
$pizza .= $food;
if (is_array($food)) {
foreach ($food as $option) {
$pizza .= " > " . $option;
if (is_array($option)) {
foreach ($option as $value) {
//etc
}
}
}
}
}
?>
To learn about the keys in an array, use the array_keys function (Demo):
$array = array(array('menu' => array(/* ... */))); # your array
print_r(array_keys($array[0])); # Array(menu)
I am returning a list of pages and their parent pages from a MySQL database and putting all results into an array as follows where every result is an array which includes the parent, name and id of the forum (the key of array pages is also the same as page id).
For the sake of the model and the applicaiton, there are some other parameters.
"root pages" have a parent of 0
there are no orphaned pages
so, the MySQL query will return this dataset.
pages=>
[1] => array(id=>1,
parent=>0,
name=>Hello World)
[2] => array(id=>1,
parent=>1,
name=>Child of Hello World)
[3] => array(id=>1,
parent=>0,
name=>Brother of Hello World)
[4] => array(id=>4,
parent=>2,
name=Grand-child of Hello World)
[6] => array(id=>6,
parent=>4,
name=Great-grand-child of Hello World)
i would then like to transform the array into something that looks like this
pages=>
[1] => id=>1,
name=>Hello World
children=>
[2] => id=>1
name=>Child of Hello World
children=>
[4] =>
id=>4
name=> Grand-child of Hello World)
children=>
[6] =>
id=>6
name=> Great-grand-child of Hello World
children= null
[3] => array(id=>1,
name=>Brother of Hello World
children=>null
So basically, i want to turn a linear array into a nested multidimensional array so that i can print my sitemap.
it needs to be a recursive solution. there are over 700 pages and up to 5 or 6 levels.
i only want to do 1 mysql query. not 700 so please dont give me a mysql based solution.
Here is a quick recursive function that builds a tree. Note that it's not great (one reason is because it doesn't get rid of items that have been already added to the tree, so each time you recurse it goes thru the entire list) - but it should work enough to get you started.
function buildTree($itemList, $parentId) {
// return an array of items with parent = $parentId
$result = array();
foreach ($itemList as $item) {
if ($item['parent'] == $parentId) {
$newItem = $item;
$newItem['children'] = buildTree($itemList, $newItem['id']);
$result[] = $newItem;
}
}
if (count($result) > 0) return $result;
return null;
}
$myTree = buildTree($myArray, 0);
<?php
$pages = array();
$pages[1] = array('id' => 1, 'parent' => 0, 'name' => 'Hello World');
$pages[2] = array('id' => 1, 'parent' => 1, 'name' => 'Child of Hello World');
$pages[3] = array('id' => 1, 'parent' => 0, 'name' => 'Brother of Hello World');
$pages[4] = array('id' => 4, 'parent' => 2, 'name' => 'Grand-child of Hello World');
$pages[6] = array('id' => 6, 'parent' => 4, 'name' => 'Great-grand-child of Hello World');
$children = array();
foreach($pages as $key => $page){
$parent = (int)$page['parent'];
if(!isset($children[$parent]))
$children[$parent] = array();
$children[$parent][$key] = array('id' => $page['id'], 'name' => $page['name']);
}
$new_pages = recursive_append_children($children[0], $children);
function recursive_append_children($arr, $children){
foreach($arr as $key => $page)
if(isset($children[$key]))
$arr[$key]['children'] = recursive_append_children($children[$key], $children);
return $arr;
}
print_r($new_pages);
?>
Outputs:
Array
(
[1] => Array
(
[id] => 1
[name] => Hello World
[children] => Array
(
[2] => Array
(
[id] => 1
[name] => Child of Hello World
[children] => Array
(
[4] => Array
(
[id] => 4
[name] => Grand-child of Hello World
[children] => Array
(
[6] => Array
(
[id] => 6
[name] => Great-grand-child of Hello World
)
)
)
)
)
)
)
[3] => Array
(
[id] => 1
[name] => Brother of Hello World
)
)