Multi-dimentional objects having multi-dimentional groups with keys php - php

I have lists of cities with areas, streets and address but I need to group them as nested objects by grouping them with if have same names.
I have objects of multiple cities with details as below:
{
"City": [
{
"area": "some name",
"colony": "some name",
"street": "some name",
"home": "some name"
}
]
}
I need to group these details as multidimentional objects in multidimentional objects.
Final Result
{
"City": [
{
"area": [
{
"colony": [
{
"street": [
{
"home": "my-home"
}
]
}
]
}
]
}
]
}

I have solved this issue. But anyhow, thanks for your efforts. Solution:
$city = $jsonObject;
$array1 = array();
foreach ($city as $object => $element) {
$array[$element['city']][] = [ 'area' => $element['area'], 'colony' => $element['colony'], 'home' => $element['home'];
}
$array2 = array();
foreach ($array1 as $object => $element) {
foreach ($element as $key => $value) {
$array1[$object][$value['area']][] = [ 'colony' => $value['colony'], 'home' => $value['home'];
}
}
$array3 = array();
foreach ($array2 as $object => $element) {
foreach ($element as $key => $value) {
foreach ($value as $row => $column) {
$array3[$object][$key][$column['colony']][] = [ 'home' => $value['home'];
}
}
}

Related

get parent nodes from a node tree array

[
{
"id": 1573695284631,
"name": "Cars",
"pid": 0,
"children": [
{
"id": 1573695292010,
"name": "Audi",
"pid": 1573695284631
},
{
"id": 1573695305619,
"name": "BMW",
"pid": 1573695284631,
"children": [
{
"id": 1573695328137,
"name": "3 Series",
"pid": 1573695305619
},
{
"id": 1573695335102,
"name": "X5",
"pid": 1573695305619
}
]
}
]
},
{
"id": 1573695348647,
"name": "Motorcycles",
"pid": 0,
"children": [
{
"id": 1573695355619,
"name": "Ducatti",
"pid": 1573695348647
}
]
}
]
Suppose I have this node-tree-like array in PHP (represented above in json for readability). For a given child node ID, I would like to find all parent node IDs that it's nested under. For example,
getParentNodes($haystack, $child_node_id=1573695328137); //[1573695284631, 1573695292010, 1573695305619]
I assume this is a use case for recursion. Here's my best attempt:
function getParentNodes($haystack, $child_node_id) {
if( empty($haystack->children) )
return;
foreach($haystack->children as $child) {
if($child->id == $child_node_id) {
// $child found, now recursively get parents
} else {
getParentNodes($child, $child_node_id);
}
}
}
This one will walk the tree until it hits the desired id.
In all cases where the leaf is not the desired one, it will return false - and collapse up the stack resulting in false or an array of parent-ids if the child is found.
Code
function getParentNodes($haystack, $child_node_id) {
foreach ($haystack as $element) {
if ($element['id'] === $child_node_id) {
// return [$element['id']]; // uncomment if you want to include child itself
return [];
} else if (array_key_exists('children', $element)) {
$parentNodes = getParentNodes($element['children'], $child_node_id);
if ($parentNodes !== false) {
return [$element['id'], ...$parentNodes];
}
}
}
return false;
}
Outputs parent ids:
array(2) {
[0]=>
int(1573695284631)
[1]=>
int(1573695305619)
}
Working example.
You missing return result. This is what you want.
function getParentNodes($arr, $child_node_id) {
$result = [];
foreach($arr as $item) {
if($item->pid == $child_node_id) {
$result[] = $item->id;
}
if(!empty($item->children)) {
$result[] = getParentNodes($item->children, $child_node_id);
}
}
return $result;
}
also you need get values as flat array
$values = getParentNodes($values, 1573695284631);
// do flat arr
array_walk_recursive($values,function($v) use (&$result){ $result[] = $v; });
// your values
var_dump($result);
Source reference for flat array
I ended up writing 2 recursive functions
function treeSearch($needle, $haystack) {
foreach($haystack as $node) {
if($node->id == $needle) {
return $node;
} elseif ( isset($node->children) ) {
$result = treeSearch($needle, $node->children);
if ($result !== false){
return $result;
}
}
}
return false;
}
treeSearch will find the node in the tree, then I need to recursively go up the tree until the parent id (pid) is 0
function getParents($node, $hierarchy, $all_parent_ids=[]) {
if($node->pid != 0) {
$parent_node = treeSearch($node->pid, $hierarchy);
$all_parent_ids[] = $parent_node->id;
$result = getParents($parent_node, $hierarchy, $all_parent_ids);
if ($result !== false){
return $result;
}
}
return $all_parent_ids;
}
then, supposing the tree is called $tree I can call them like:
$node = treeSearch(1573695328137, $tree);
$parents = getParents($node, $tree);
This is the best solution to take the parent of a child !
function getPathParent($id, $tree='',$opts='', &$path = array()) {
$in = array_replace(array(
'id'=>'id',
'child'=>'children',
'return'=>'id'
),(array)$opts);
if ( is_array($tree) && !empty($tree) ){
foreach ($tree as $item) {
if ($item[$in['id']] == $id) {
array_push($path, $item[$in['return']]);
return $path;
}
if ( isset($item[$in['child']]) && !empty($item[$in['child']]) ) {
array_push($path, $item[$in['return']]);
if (getPathParent($id, $item[$in['child']],$opts, $path) === false) {
array_pop($path);
} else {
return $path;
}
}
}
}
return false;
}
$tree = [
[
"id" => 1573695284631,
"name" => "Cars",
"pid" => 0,
"children" => [
[
"id" => 1573695292010,
"name" => "Audi",
"pid" => 1573695284631
],
[
"id" => 1573695305619,
"name" => "BMW",
"pid" => 1573695284631,
"children" => [
[
"id" => 1573695328137,
"name" => "3 Series",
"pid" => 1573695305619
],
[
"id" => 1573695335102,
"name" => "X5",
"pid" => 1573695305619
]
]
]
]
],
[
"id" => 1573695348647,
"name" => "Motorcycles",
"pid" => 0,
"children" => [
[
"id" => 1573695355619,
"name" => "Ducatti",
"pid" => 1573695348647
]
]
]
];
$getParentNode = getPathParent(1573695335102,$tree);
var_export($getParentNode);
// return:
/*
array (
0 => 1573695284631,
1 => 1573695305619,
2 => 1573695335102,
)
*/
$getParentNode = getPathParent(1573695335102,$tree,array('return'=>'name'));
var_export($getParentNode);
// return:
/*
array (
0 => 'Cars',
1 => 'BMW',
2 => 'X5',
)
*/
$getParentNode = getPathParent(1573695335102,$tree,array('id'=>'id','child'=>'children','return'=>'pid'));
var_export($getParentNode);
// return:
/*
array (
0 => 0,
1 => 1573695284631,
2 => 1573695305619,
)
*/

How do I put multiple values in an array while foreaching through values in PHP

Alright so I'm trying to adjust an array and decode it to json, currently it decodes the array like this;
{"campaignId":"18210f12-502c-4d71-a098-4f595304a8d0","fields.CPLastName":"Voornaam 1","fields.CPFirstname":"Achternaam 1","fields.OROrganisation":"Bedrijf 1"}
{"campaignId":"18210f12-502c-4d71-a098-4f595304a8d0","fields.CPLastName":"Voornaam 2","fields.CPFirstname":"Achternaam 2","fields.OROrganisation":"Bedrijf 2"}
Code:
$request = array();
foreach($address_data as $address) {
foreach($address as $key => $value){
if($key == 'campaignId') {
$request[$key] = $value;
}
if (strpos($key, 'fields') !== false) {
$fields = explode('.', $key);
$request['fields'] = array(
array('fieldId' => $fields[1], 'value' => $value)
);
}
}
echo json_encode($request);
}
What I want to do is, where it says; fields. I want to explode on that and replace fields. with fieldId within a fields array. So something like this;
$request['fields'] = array(array('fieldId' => $key, 'value' => $value));
Now for some reason it will only do the last key, and I want it to loop through all the keys where it says 'fields.'
So the final request should look something like;
{
"campaignId":"18210f12-502c-4d71-a098-4f595304a8d0",
"fields": [
{
"fieldId":"CPLastName",
"value":"Voornaam 1"
},
{
"fieldId": "CPFirstname",
"value": "Achternaam 1"
},
{
"fieldId":"OROrganisation",
"value":"Bedrijf 1"
}
]
}
{
"campaignId":"18210f12-502c-4d71-a098-4f595304a8d0",
"fields": [
{
"fieldId":"CPLastName",
"value":"Voornaam 2"
},
{
"fieldId": "CPFirstname",
"value": "Achternaam 2"
},
{
"fieldId":"OROrganisation",
"value":"Bedrijf 2"
}
]
}
Use a temporary helper variable in cases like this, that you assemble the array data structure for a single item in.
Add that temp array to the result array at the end of the outer loop.
$request = [];
foreach($address_data as $address) {
$temp = [];
foreach($address as $key => $value){
if($key == 'campaignId') {
$temp[$key] = $value;
}
if (strpos($key, 'fields') !== false) { // === 0 would perhaps make more sense here
$fields = explode('.', $key);
$temp['fields'][] = [
'fieldId' => $fields[1],
'value' => $value
];
}
}
$request[] = $temp;
}
echo json_encode($request);

How to fetch Array from .json in PHP

I have json document with Indian States[Cities[Area]], similar to the following:
{
"Andaman and Nicobar Islands": [{
"Port Blair": [
"Aberdeen Bazaar",
"Bidhabad Village",
"Chidiyatapu",
"Corbyns Cove",
"Dollygunj",
"Ferrurgunj",
"Goalghar",
"Goodwill Estate",
"Junglighat",
"Marine Hill",
"Phoenix Bay",
"South Point"
]
},
{
"Havelock Island": [
"Govindnagar Beach",
"Radhanagar Beach",
"Vijaynagar Beach"
]
},
{
"Neil Island": [
"Ramnagar",
"Bharat Pur",
"Sitapur Beach",
"Laxmanpur",
"Neil Kendra"
]
}....
}
I want to fetch this array in this format:
$stateData['Andaman and Nicobar Islands'] => [
"Port Blair" => [
"Aberdeen Bazaar" => "Aberdeen Bazaar",
"Bidhabad Village" => "Bidhabad Village"
.
.
.
]
]
and so on...
I have this Json data in a json file and assign the value to a variable $stateData using $stateData = (array)json_decode(fread($file, filesize(public_path('india_state_city1.json'))));
I assume that your json is saved in a variable called $states.
foreach (json_decode($states) as $key => $state) {
foreach ($state as $stateData) {
foreach ($stateData as $key2 => $city) {
foreach ($city as $key3 => $cit) {
$res[$key][$key2][$cit] = $cit;
}
}
}
}
The output:
Check the Demo: https://paiza.io/projects/NlK9g5jluy8Lz9kmhMW69Q
i got that you want to make the area array to be associative and the id,value is same.
i f i'm right you can do this :
foreach ($stateData['Andaman and Nicobar Islands'] as &$array_1) {
foreach ($array_1 as &$area_array){
$formatted_array = [];
foreach ($area_array as $area){
$formatted_array[$area] = $area;
}
$area_array = $formatted_array;
}
}
long but simple solution i think
in my opinion json_decode function will help with second parameter passed as true
because it will convert every inner object to array
by converting to array we can easily use the state,city and area name and if you want ordering even you can do that by key no of array
<?php
$data = '{
"Andaman and Nicobar Islands": [
{
"Port Blair": [
"Aberdeen Bazaar",
"Bidhabad Village",
"Chidiyatapu",
"Corbyns Cove",
"Dollygunj",
"Ferrurgunj",
"Goalghar",
"Goodwill Estate",
"Junglighat",
"Marine Hill",
"Phoenix Bay",
"South Point"
]
},
{
"Havelock Island": [
"Govindnagar Beach",
"Radhanagar Beach",
"Vijaynagar Beach"
]
},
{
"Neil Island": [
"Ramnagar",
"Bharat Pur",
"Sitapur Beach",
"Laxmanpur",
"Neil Kendra"
]
}
]
}';
$indian_states = json_decode($data,TRUE);
foreach ($indian_states as $stateName=>$statesCities)
{
echo $stateName;
foreach ($statesCities as $citiNo=>$cityAreas)
{
echo '<br /> |---'; //comment this line
foreach ($cityAreas as $citiName=>$areas)
{
echo $citiName;
foreach ($areas as $areaName){
echo "<br /> |---"; //comment this line echo $areaName;echo '<br />';
}
}
}
}
?>
output

Specific problem with traversing an array in php

I have given the array:
array(
"firstName": null,
"lastName": null,
"category": [
"name": null,
"service": [
"foo" => [
"bar" => null
]
]
]
)
that needs to be transform into this:
array(
0 => "firstName",
1 => "lastName",
2 => "category",
"category" => [
0 => "name",
1 => "service",
"service" => [
0 => "foo",
"foo" => [
0 => "bar"
]
]
]
)
The loop should check if a value is an array and if so, it should add the key as a value (0 => category) to the root of array and then leave the key as it is (category => ...) and traverse the value again to build the tree as in example.
I am stuck with this and every time I try, I get wrong results. Is there someone who is array guru and knows how to simply do it?
The code so far:
private $array = [];
private function prepareFields(array $fields):array
{
foreach($fields as $key => $value)
{
if(is_array($value))
{
$this->array[] = $key;
$this->array[$key] = $this->prepareFields($value);
}
else
{
$this->array[] = $key;
}
}
return $this->array;
}
You could make use of array_reduce:
function prepareFields(array $array): array
{
return array_reduce(array_keys($array), function ($result, $key) use ($array) {
$result[] = $key;
if (is_array($array[$key])) {
$result[$key] = prepareFields($array[$key]);
}
return $result;
});
}
Demo: https://3v4l.org/3BfKD
You can do it with this, check the Demo
function array_format(&$array){
$temp_array = [];
foreach($array as $k=>$v){
$temp_array[] = $k;
if(is_array($v)){
array_format($v);
$temp_array[$k] = $v;
}
}
$array = $temp_array;
}
array_format($array);
print_r($array);

how to foreach in inner array

in my relation database,
if id_sub_bidang = 1 then nama_sub_bidang "frontend deveoper".
if id_sub_bidang = 2 then nama_sub_bidang "senior marketing"
my code
$data = Company::find($id);
$result_data = array();
foreach ($data->posting_job as $hasil) {
foreach ($data->sub_bidang as $value) {
$result_data[] = [
'id_sub_bidang' => $hasil->id_sub_bidang,
'nama_sub_bidang' => $value->nama
];
}
}
return response()->json($result_data);
the output
[
{
"id_sub_bidang": 1,
"nama_sub_bidang": "Frontend Developer"
},
{
"id_sub_bidang": 1,
"nama_sub_bidang": "Senior Marketing"
},
{
"id_sub_bidang": 2,
"nama_sub_bidang": "Frontend Developer"
},
{
"id_sub_bidang": 2,
"nama_sub_bidang": "Senior Marketing"
}
]
expected result
[
{
"id_sub_bidang": 1,
"nama_sub_bidang": "Frontend Developer"
},
{
"id_sub_bidang": 2,
"nama_sub_bidang": "Senior Marketing"
}
]
i want to loop in inner array but doesnt work. so, i use this way.
what the problem ?
Change your foreach loops to this:
foreach ($data->posting_job as $hasil) {
foreach ( $hasil->id_sub_bidang as $hasilid) {
$result_data[] = ['id_sub_bidang' => $hasil->id_sub_bidang];
foreach ($data->sub_bidang as $value) {
$result_data[] = ['nama_sub_bidang' => $value->nama];
}
}
}
Build an array then using the method recursive to clean the array by duplicate entry.
array_replace_recursive
Another solution
$empty_stats = Array(
'id_sub_bidang' => null,
'nama_sub_bidang' => null
);
foreach ($array as $value) {
if (!array_key_exists($id_sub_bidang, $array)) {
$array[] = $empty_stats;
}
$array[] = [
'id_sub_bidang' => $hasil->id_sub_bidang,
'nama_sub_bidang' => $value->nama
];
}

Categories