How to recursively remap array in PHP? - php

How to recursively remap children to nodes? I tried writing recursive function, but it only runs one iteration. Array map - http://php.net/manual/en/function.array-map.php would only run for single dimension
I'm using nested sets model https://github.com/etrepat/baum#getting-started Input is generated by dumping all hierarchy
$array = Category::where('name', '=', 'All')->first()->getDescendantsAndSelf()->toHierarchy()->toArray();
/* Input */
$array = array(
'category_id' => 0,
'children' => array(
array(
'category_id' => 1,
'children' => array(
'category_id' => 2,
'children' => array(
'category_id' => 3,
)
)
),
array(
'category_id' => 4,
'children' => array(
'category_id' => 5,
'children' => array(
'category_id' => 6,
)
)
)
)
);
Output should be
/*
$array = array(
'category_id' => 0,
'nodes' => array(
array(
'category_id' => 1,
'nodes' => array(
'category_id' => 2,
'nodes' => array(
'category_id' => 3,
)
)
),
array(
'category_id' => 4,
'nodes' => array(
'category_id' => 5,
'nodes' => array(
'category_id' => 6,
)
)
)
)
);*/
function remap($items){
if(!empty($items['children'])){
$items['nodes'] = $items['children'];
unset($items['children']);
return remap($items['nodes']);
}
else{
return $items;
}
}
print_r(remap($array));

A bit complicated couse , childrens content variates by depth
function remap(array &$items){
if(array_key_exists('children',$items)){
$items['nodes'] = $items['children'];
unset($items['children']);
if(array_key_exists('children',$items['nodes'])){
$items['nodes']['nodes'] = $items['nodes']['children'];
unset($items['nodes']['children']);
}
foreach ($items['nodes'] as &$x) {
if (is_array($x)) {
remap($x);
}
}
}
else{
return $items;
}
}
remap($array);
print_r($array);

This function will change the children keys to nodes.
function remap($items) {
$result = array();
foreach ($items as $key => $value) {
if ($key == 'children') {
$result['nodes'] = remap($value);
} else {
$result[$key] = $value;
}
}
return $result;
}
$new_array = remap($array);
After your comment, though, it seems like it would be easier to create an accessor that maps children to nodes in your Eloquent model and use that in the select that gets your collection.

Related

show array child dependent of the another array child member

i have an array, and i want to show the array values if the name of same array repeat in another array and have true as value
my arrays like this
$array1 = [
array(
'id' => 1
'name' => internal_evidence
'price' => 30
'course_id' => 3
),
array(
'id' => 2
'name' => international_evidence
'price' => 450
'course_id' => 3
),
array(
'id' => 3
'name' => internal_evidence
'price' => 10
'course_id' => 1
),
array(
'id' => 4
'name' => technical_evidence
'price' => 134
'course_id' => 3
),
];
$array2 = [
array(
'id' => 3
'name' => graphic
'price' => 150
'attr' => array(
'internal_evidence' => 'true',
'international_evidence' => 'false',
'technical_evidence' => 'true'
)
),
array(
'id' => 5
'name' => 3dmax
'price' => 300
'attr' => array(
)
),
array(
'id' => 1
'name' => ICDL
'price' => 480
'attr' => array(
'internal_evidence' => 'true',
)
),
];
I want to access and show all attr members with value true in array2
Also, the course_id from array1 must be the same as id in array2
Like this:
<p>internal_evidence with id=1 and price=30 </p>
<p>technical_evidence with id=4 and price=134 </p>
<p>internal_evidence with id=3 and price=10 </p>
i tried this code but its don`t work properly
$array1ByIdAndName = array_reduce($array1, static function ($byIdAndName, $entry) {
$byIdAndName[$entry['product_id']][$entry['e_name']] = $entry;
return $byIdAndName;
});
$array2 = array_map(static function ($entry) use ($array1ByIdAndName) {
$entry['total_price'] = $entry['price'];
$entry['attr'] = array_reduce(array_keys($entry['attr']), static function ($attrs, $attrName) use ($array1ByIdAndName, &$entry) {
if ($entry['attr'][$attrName] === 'true') {
$attrs[] = $attrName;
$entry['total_price'] += $array1ByIdAndName[$entry['id']][$attrName]['price'];
}
return $attrs;
}, []);
return $entry;
}, $array2);
you should know to i dont want to show by id in array1 and array2. i want to show by course_id in array1 in array2 with true value in attr member in array2
you can just use this code
$array1ByIdAndName = array_reduce($array1, static function ($byIdAndName, $entry) {
$byIdAndName[$entry['course_id']][$entry['name']] = $entry;
return $byIdAndName;
});
$array2 = array_map(static function ($entry) use ($array1ByIdAndName) {
$entry['total_price'] = $entry['price'];
$entry['attr'] = array_reduce(array_keys($entry['attr']), static function ($attrs, $attrName) use ($array1ByIdAndName, &$entry) {
if ($entry['attr'][$attrName] === 'true') {
$attrs[] = $attrName;
$entry['total_price'] += $array1ByIdAndName[$entry['id']][$attrName]['price'];
$entry[$attrName] = $array1ByIdAndName[$entry['id']][$attrName]['price'];
}
return $attrs;
}, []);
return $entry;
}, $array2);
echo '<pre>';
print_r($array2);

set php variable contains only selected array

I have these array but I wanted it to echo an array only for the "watch" category and wanted to store the selected array in a PHP variable, I have to try to search the web to find the solution but no success.
$arr = [
'status' => 1,
'msg' => [
'total_records' => 5,
'total_pages' => 1,
'page_number' => 1,
'per_page' => 100,
'return_count' => 5,
'page_result' => [
0 => array
(
'items' => 200052001,
'code' => 501,
'category' => 'watch',
'price' => 50,
'stock' => 1,
),
1 => array
(
'items' => 200052001,
'code' => 401,
'category' => 'shirt',
'price' =>3,
'stock' => 1,
),
2 => array
(
'items' => 200052001,
'code' => 172758801,
'category' => 'watch',
'price' => 200,
'stock' => 1,
),
],
],
'errcode' => 0,
];
This should do the trick.
$watch_array = array();
foreach($arr["msg"]["page_result"] AS $k => $item) {
if($item["category"] == "watch") {
$watch_array[] = $item;
}
}
You now have an array containing only the watch.
To display its content, use:
print_r($watch_array);
Demo Link.
Check this search function for your requirement. Its completely dynamic along with recursive nature.
function search($array, $key, $value)
{
$results = [];
if (is_array($array)) {
if (isset($array[$key]) && $array[$key] == $value) {
$results[] = $array;
}
foreach ($array as $subarray) {
$results = array_merge($results, search($subarray, $key, $value));
}
}
return $results;
}
$temp = search($arr, "category", "watch");
Source.

Array to string conversion is not working in opencart?

Actually I want to convert array data to string data for that I
amusing implode() function by comma separator but it is throwing error.
Below is my code:-
$total_data = array();
$category_return = $this->model_catalog_category->category_name_get();
//print_r($category_return);die;
foreach ($category_return as $total) {
$total_data[] = array(
'category_id' => $total['category_id'],
'parent_id' => $total['category_id'],
'name' => $total['name']
);
}
$data = $total_data;
//print_r($data);die;
$fields = implode(',',$data);
echo $fields; die;
Try this:
$total_data = array(
array(
'category_id' => 2,
'parent_id' => 1,
'name' => 'First Cat'
),
array(
'category_id' => 1,
'parent_id' => 0,
'name' => 'Parent Cat'
),
array(
'category_id' => 3,
'parent_id' => 2,
'name' => 'Parent Cat3'
)
);
$output = implode(",", array_map(function($a) { return implode(",", $a); }, $total_data));
print_r($output);
Output:
2,1,First Cat,1,0,Parent Cat,3,2,Parent Cat3

Search value in array and if not found added

I have an array with the following format:
$array = Array(
Array('id' => 77, 'title' => 'title'),
Array('id' => 43, 'title' => 'title2'),
Array('id' => null, 'title' => 'title3'),
Array('id' => null, 'title' => null),
);
This array is populated dynamically, this is just an example. Also, i have a second array with the format:
$searchingArray = Array('43', '5');
The main idea is to search if values from $searchingArray are in $array and if not exists then added. My function is:
function addId($id, $ignoreIfFound=false) {
foreach ($array as $values) {
if ($values['id'] and $values['id'] == $id) {
if (!$ignoreIfFound) {
$array[] = Array('id' => $id, 'title' => 'test5');
break;
}
else{
// do nothing
}
}else{
$array[] = Array('id' => $id, 'title' => 'test5');
break;
}
}
}
foreach ($searchingArray as $id) {
$this->addId($id, true);
}
For given example the result should be:
$array = Array(
Array('id' => 77, 'title' => 'title'),
Array('id' => 43, 'title' => 'title2'),
Array('id' => null, 'title' => 'title3'),
Array('id' => null, 'title' => null),
Array('id' => 5, 'title' => 'test5'),
);
Can you tell me what it is wrong with my code?
This should work for you:
First extract the id column out of your array with array_column(). After this simply loop through your search array and check with in_array() if they id already exists or not. If not simply add it to the array.
$ids = array_column($array, "id");
foreach($searchingArray as $search) {
if(!in_array($search, $ids)) {
$array[] = ["id" => $search, "title" => "title" . $search];
}
}

Recursive get path from multidimensional php array

I have array:
$adm_menu_old = array (
array(
'id' => 1,
'name' => 'Test1',
),
array(
'id' => 3,
'name' => 'Test3',
'childrens' => array(
array(
'id' => 31,
'name' => 'Test31',
),
array(
'id' => 32,
'name' => 'Test32',
'childrens' => array(
array(
'id' => 321,
'name' => 'Test321',
),
),
)
),
array(
'id' => 4,
'name' => 'Test4',
),
);
Say i know id value.
I need get path with all parents of this id.
For example i need get path to this element: id=321
i need get array with key name values:
array('Test3','Test32','Test321')
how should look like recursive function?
Try this function:
function getNames($id, $arr) {
$result = array();
foreach($arr as $key => $val) {
if(is_array($val)) {
if($val["id"] == $id) {
$result[] = $val["name"];
} elseif(!empty($val["childrens"]) && is_array($val["childrens"])) {
$sub_res = getNames($id, $val["childrens"]);
if(count($sub_res) > 0) {
$result[] = $val["name"];
$result = array_merge($result, $sub_res);
}
}
}
}
return $result;
}

Categories