how to foreach in inner array - php

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
];
}

Related

PHP merge array by "depth"? [duplicate]

This question already has answers here:
How to array_merge_recursive() an array?
(2 answers)
Closed 3 months ago.
I have an array like this:
[
{
"function_1": {
"element": {
"error": "0",
"msg": "test"
}
}
},
{
"function_1": {
"element_2": {
"error": "0",
"msg": "test"
}
}
},
{
"function_2": {
"element": {
"error": "0",
"msg": "test"
}
}
},
{
"function_2": {
"element_2": {
"error": "0",
"msg": "test"
}
}
}
]
I want output like this:
[
{
"function_1": {
"element": {
"error": "0",
"msg": "test"
},
"element_2": {
"error": "0",
"msg": "test"
}
}
},
{
"function_2": {
"element": {
"error": "0",
"msg": "test"
},
"element_2": {
"error": "0",
"msg": "test"
}
}
}
]
The answers that I found offered to search by name("function_1", "function_2"). But this does not suit me, the function will not always pass an array. I need exactly the "depth" or any other reasonable way.
Thank you!
To achieve your desired result, you could json-decode, recursively merge each individual subarray, then loop over that structure to push each item as a second-level array like this: (Demo)
$array = json_decode($json, true);
$merged = array_merge_recursive(...$array);
$result = [];
foreach ($merged as $key => $data) {
$result[] = [$key => $data];
}
var_export($result);
But I can't imagine getting any benefit from adding unnecessary depth to your result array. I recommend simply json decoding, then calling array_merge_recursive() with the spread operator: (Demo)
var_export(
array_merge_recursive(
...json_decode($json, true)
)
);
Output:
array (
'function_1' =>
array (
'element' =>
array (
'error' => '0',
'msg' => 'test',
),
'element_2' =>
array (
'error' => '0',
'msg' => 'test',
),
),
'function_2' =>
array (
'element' =>
array (
'error' => '0',
'msg' => 'test',
),
'element_2' =>
array (
'error' => '0',
'msg' => 'test',
),
),
)
Your data structure looks weird for the purpose you are trying to achieve I'm bored af tho and created this code for you
function combineElementsPerfunction($functions) {
$result = [];
$uniqueFunctions = [];
foreach ($functions as $function) {
$functionName = array_keys($function)[0];
$uniqueFunctions[] = $functionName;
}
$uniqueFunctions = array_unique($uniqueFunctions);
foreach ($uniqueFunctions as $uniqueFunction) {
$functionObjects = array_filter(
$functions,
function($function) use ($uniqueFunction) {
$functionName = array_keys($function)[0];
return $functionName === $uniqueFunction;
}
);
$elements = [];
foreach ($functionObjects as $functionObject) {
$function = array_shift($functionObject);
$elements = array_merge($elements, $function);
}
$result[] = [
$uniqueFunction => $elements
];
}
return $result;
}
function changeArr($data){
$box = $new = [];
foreach ($data as $v){
$key = array_key_first($v);
$i = count($box);
if(in_array($key, $box)){
$keys = array_flip($box);
$i = $keys[$key];
}else{
$box[] = $key;
}
$new[$i][$key] = isset($new[$i][$key]) ? array_merge($new[$i][$key], $v[$key]) : $v[$key];
}
return $new;
}

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 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

How to get join table data and pass inside array in php

I have two tables order and orderDetail. i have multiple delivery address in order detail table based on id of order table
i want to display id from order table and deliveryAddress from order detail table.i am getting below output when i print..
but unable to display delivery_address.please anyone can suggest how i display delivery_address..
{
"responseData": {
"status": 1,
"message": "",
"result": [
{
"Order": {
"id": "677",
"detail_location_instructions": "Near Inox"
},
"OrderDetail": [
{
"order_id": "677",
"delivery_address": "Smart Club Gimnasio - Avenida Álvarez Thomas, Buenos Aires, Autonomous City of Buenos Aires, Argentina"
},
{
"order_id": "677",
"delivery_address": "Lower Fort Street, Dawes Point, New South Wales, Australia"
}
]
},
{
"Order": {
"id": "680"
},
"OrderDetail": []
},
{
"Order": {
"id": "684"
},
"OrderDetail": [
{
"order_id": "684",
"delivery_address": "Four Seasons - Posadas"
}
]
}
]
}
}
below is my code
public function getOrderlist(){
if($this->processRequest){
$err = false;
if(empty($this->requestData['id'])){
$this->responceData['message'] = "Please provide User ID";
$err = true;
}
if(!$err){
$id = trim($this->requestData['id']);
$conditions = array('Order.user_id'=>$id);
$data = $this->Order->find('all',array('conditions'=>$conditions));
if(!empty($data)){
$c = array();
foreach ($data as $key => $value) {
$c[] = array(
'Id' => $value['Order']['id'],
'deliveryAddress' => $value['OrderDetail']['delivery_address']
);
}
}
$this->responceData['result'] = $c;
$this->responceData['status'] = 1;
}
}
}
You have to put the deliveryAddress in array
$c = array();
foreach ($data as $key => $value) {
$myOrders = [
'Id'=>$value['Order']['id'],
'deliveryAddress'=>[]
];
foreach($value['OrderDetail'] as $address){
$myOrders['deliveryAddress'][] = $address['delivery_address'];
}
$c[] = $myOrders;
}
Hope this will help
can you trying below code.
foreach ($data as $key => $value) {
$c[] = array(
'Order' => array(
'id'=>$value['Order']['id'],
'detail_location_instructions' => $value['Order']['detail_location_instructions'],
),
'OrderDetail' => array(
'order_id'=>$value['Order']['id'],
'deliveryAddress' => $value['OrderDetail']['delivery_address'],
),
)
}
There is cases where you dont get the delivery address, in that case, you need to check if it exists first. use the Hash utility for that purpose.
I transformed the data to an array, in order for the class Hash to work.
public function getOrderlist(){
if($this->processRequest){
$err = false;
if(empty($this->requestData['id'])){
$this->responceData['message'] = "Please provide User ID";
$err = true;
}
if(!$err){
$id = trim($this->requestData['id']);
$conditions = array('Order.user_id'=>$id);
$data =(array) $this->Order->find('all',array('conditions'=>$conditions));
if(!empty($data)){
$c = array();
foreach ($data as $key => $value) {
$c[] = array(
'Id' => Hash::get($value, 'Order.id'),
'deliveryAddress' => current(Hash::extract($value, 'OrderDetail.{n}.delivery_address', array()))
);
}
}
$this->responceData['result'] = $c;
$this->responceData['status'] = 1;
}
}
}

Multi-dimentional objects having multi-dimentional groups with keys 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'];
}
}
}

Categories