Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I have an array with the following structure:
Array
(
[25] => Array
(
[id] => 25
[level] => 0
[children] => Array
(
)
[name] => Databases
[parent_id] => 1
)
[34] => Array
(
[id] => 34
[level] => 0
[children] => Array
(
[35] => Array
(
[id] => 35
[level] => 0
[children] => Array
(
)
[name] => Call Center
[parent_id] => 34
)
[51] => Array
(
[id] => 51
[level] => 0
[children] => Array
(
[75] => Array
(
[id] => 75
[level] => 0
[children] => Array
(
)
[name] => Accounts
[parent_id] => 51
)
)
[name] => Payment System
[parent_id] => 34
)
)
[name] => proyects
[parent_id] => 1
)
)
I need to assign the item level of each child in the position where the element is, for example:
Array
(
[25] => Array
(
[id] => 25
[level] => 0
[children] => Array
(
)
[name] => Databases
[parent_id] => 1
)
[34] => Array
(
[id] => 34
[level] => 0
[children] => Array
(
[35] => Array
(
[id] => 35
[level] => 1
[children] => Array
(
)
[name] => Call Center
[parent_id] => 34
)
[51] => Array
(
[id] => 51
[level] => 2
[children] => Array
(
[75] => Array
(
[id] => 75
[level] => 1
[children] => Array
(
)
[name] => Accounts
[parent_id] => 51
)
)
[name] => Payment System
[parent_id] => 34
)
)
[name] => proyects
[parent_id] => 1
)
)
I use this code in the link below and does not work as expected.
http://codepad.org/TqktuMdW
<?php
$list = array(
25 => array(
'id' => 25,
'name' => 'Databases',
'parent_id' => 1,
),
34 => array(
'id' => 34,
'name' => 'proyects',
'parent_id' => 1,
),
35 => array(
'id' => 35,
'name' => 'Call Center',
'parent_id' => 34,
),
51 => array(
'id' => 51,
'name' => 'Payment System',
'parent_id' => 34,
),
75 => array(
'id' => 75,
'name' => 'Accounts',
'parent_id' => 51,
),
);
$cats = array(1,2,3,4,5);
$boards = getBoardIndex($list,$cats);
print '<pre>'; print_r($boards); print '</pre>';
function getBoardIndex($data, $parent_id, $tree = array())
{
foreach($data as $idx => $row)
{
if(in_array($row['parent_id'], array_values($parent_id)))
{
foreach($row as $k => $v)
{
$tree[$row['id']][$k] = $v;
$tree[$row['id']]['level'] = in_array($row['parent_id'],array_values($parent_id)) ? 0 : array_search($k,array_keys($row));
unset($data[$idx]);
$tree[$row['id']]['children'] = getBoardIndex($data,array($row['id']));
}
}
}
ksort($tree);
return($tree);
}
?>
What is the best way to do that?
Create a recursive function and use it
function assignLevels($array, $level=0) {
foreach($array as $key => $subarray) {
$array[$key]['children'] = assignLevels($subarray['children'], $level+1);
$array[$key]['level'] = $level;
}
return $array;
}
Pass it your array and it will return the same array with levels assigned. Just tested it
Related
I need to subtract the qt from two arrays based on id and type, keeping the array complete.
How do I do in php to be able to subtract these arrays?
I have 2 arrays:
=> this is the first array with multiple key "down"
Array
(
[0] => Array
(
[id] => 26
[loc] => 1
[type] => down
[qt] => 12
)
[1] => Array
(
[id] => 32
[loc] => 1
[type] => down
[qt] => 34
)
[2] => Array
(
[id] => 26
[loc] => 2
[type] => down
[qt] => 5
)
[3] => Array
(
[id] => 86
[loc] => 3
[type] => down
[qt] => 45
)
[4] => Array
(
[id] => 23
[loc] => 9
[type] => down
[qt] => 3
)
[5] => Array
(
[id] => 23
[loc] => 3
[type] => down
[qt] => 99
)
)
=> this is the second array with multiple key "up"
Array
(
[0] => Array
(
[id] => 26
[loc] => 1
[type] => up
[qt] => 5
)
[1] => Array
(
[id] => 86
[loc] => 3
[type] => up
[qt] => 27
)
[2] => Array
(
[id] => 23
[loc] => 9
[type] => up
[qt] => 3
)
)
=> I need cubtract "qt" (if "id" and "loc" are the same then subtract the "qt")
Array
(
[0] => Array
(
[id] => 26
[loc] => 1
[type] => total
[qt] => 7
)
[1] => Array
(
[id] => 32
[loc] => 1
[type] => total
[qt] => 34
)
[2] => Array
(
[id] => 26
[loc] => 2
[type] => total
[qt] => 5
)
[3] => Array
(
[id] => 86
[loc] => 3
[type] => total
[qt] => 18
)
[4] => Array
(
[id] => 23
[loc] => 9
[type] => total
[qt] => 0
)
[5] => Array
(
[id] => 23
[loc] => 3
[type] => down
[qt] => 99
)
)
Try this out
function findMatch($array, $id, $loc)
{
foreach ($array as $key => $item) {
if ($item["id"] == $id and $item["loc"] == $loc) {
return $key;
}
}
return false;
}
$total = [];
foreach($down as $d) {
$matched = findMatch($up, $d["id"], $d["loc"]);
if($matched !== false){
$total[] = array_replace($d, [
"type" => "total",
"qt" => ($d["qt"] - $up[$matched]["qt"])
]);
} else {
$total[] = array_replace($d, ["type" => "total"]);
}
}
print_r($total);
I have an array that looked like this
Array
(
[child-safety-lock] => Array
(
[0] => Array
(
[id] => 652
[name] => CHILD LOCK (YES/NO)
)
[1] => Array
(
[id] => 336
[name] => CHILD LOCK (YES/NO)
)
[2] => Array
(
[id] => 19
[name] => Child Lock
)
[3] => Array
(
[id] => 398
[name] => CHILD LOCK (YES/NO)
)
[4] => Array
(
[id] => 155
[name] => CHILD SAFETY LOCK
)
[5] => Array
(
[id] => 329
[name] => CHILD LOCK
)
[6] => Array
(
[id] => 96
[name] => CHILD LOCK
)
[7] => Array
(
[id] => 184
[name] => CHILD SAFETY LOCK
)
[8] => Array
(
[id] => 875
[name] => CHILD SAFETY LOCK (YES/NO)
)
[9] => Array
(
[id] => 450
[name] => CHILD LOCK (YES/NO)
)
[10] => Array
(
[id] => 149
[name] => CHILD SAFE LOCK
)
[11] => Array
(
[id] => 374
[name] => CHILD LOCK (YES/NO)
)
[12] => Array
(
[id] => 491
[name] => CHILD LOCK (YES/NO)
)
[13] => Array
(
[id] => 622
[name] => CHILD LOCK (YES/NO)
)
[14] => Array
(
[id] => 1309
[name] => CHILD LOCK (YES/NO)
)
[15] => Array
(
[id] => 1336
[name] => CHILD LOCK (YES/NO)
)
[16] => Array
(
[id] => 1466
[name] => CHILD LOCK (YES/NO)
)
[17] => Array
(
[id] => 1577
[name] => CHILD SAFETY LOCK (YES/NO)
)
[18] => Array
(
[id] => 1715
[name] => CHILD SAFETY LOCK (YES/NO)
)
[19] => Array
(
[id] => 1908
[name] => CHILD LOCK (YES/NO)
)
)
[controls] => Array
(
[id] => 84
[name] => CONTROLS (E.G. TOUCH, DIAL )
)
[turntable-mm] => Array
(
[id] => 77
[name] => TURNTABLE SIZE (MM)
)
[display-type] => Array
(
[id] => 78
[name] => DISPLAY (E.G. LED, LCD, TFT ETC)
)
[smart-inverter-technology] => Array
(
[id] => 83
[name] => SMART INVERTER TECHNOLOGY
)
[power-w] => Array
(
[id] => 80
[name] => POWER LEVEL (W)
)
[capacity-l] => Array
(
[id] => 79
[name] => CAPACITY (L)
)
[steam] => Array
(
[id] => 86
[name] => STEAM FUNCTION
)
[grill-function] => Array
(
[id] => 89
[name] => GRILL FUNCTION
)
[sensor-cook] => Array
(
[id] => 91
[name] => SENSOR COOK
)
[quick-start] => Array
(
[id] => 92
[name] => QUICK START
)
[defrost-function] => Array
(
[id] => 93
[name] => DEFROST
)
[keep-warm-function] => Array
(
[id] => 97
[name] => KEEP WARM
)
[time-remaining-display] => Array
(
[id] => 98
[name] => TIME REMAINING DISPLAY
)
[reheat-function] => Array
(
[id] => 95
[name] => REHEAT
)
[optional-trim-kit] => Array
(
[id] => 99
[name] => TRIM KIT
)
)
How can I return the key 'child-safety-lock' for example if I enter 652 or 336? Another example is returning array key 'controls' if I enter id '84'? I tried using array_filter() for this but i can't make it work, Is there someone might point me in the right direction?
Also have this function but this is not working
function in_array_r($needle, $haystack, $strict = false) {
foreach ($haystack as $item) {
if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && in_array_r($needle, $item, $strict)!==FALSE)) {
return key($haystack);
}
}
return false;
}
The following should work -
// Reconstruct array to simplify
$temp = [];
foreach ($arr as $key => $val) {
$temp[$key] = $val[0];
}
// extract key & required values to a temporary array
$temp = array_combine(array_keys($temp), array_column($temp, 'id'));
// look for the values and extract the key
$key = array_search(84, $temp);
References -
https://www.php.net/manual/en/function.array-search.php
https://www.php.net/manual/en/function.array-combine.php
https://www.php.net/manual/en/function.array-column.php
Create separate arrays and access it via index:
$data = [
'child-safety-lock' => [
['id' => 652, 'name' => 'CHILD LOCK (YES/NO)'],
['id' => 336, 'name' => 'CHILD LOCK (YES/NO)'],
['id' => 19, 'name' => 'Child Lock'],
],
'controls' => [
'id' => 84, 'name' => 'CONTROLS (E.G. TOUCH, DIAL )'
]
];
$childSafetyLock = array_column($data['child-safety-lock'], 'name', 'id');
$controls = array_column([$data['controls']], 'name', 'id');
var_dump(
$childSafetyLock[652],
$childSafetyLock[336],
$controls[84],
);
or more universal solution:
$data = [
'child-safety-lock' => [
['id' => 652, 'name' => 'CHILD LOCK (YES/NO)'],
['id' => 336, 'name' => 'CHILD LOCK (YES/NO)'],
['id' => 19, 'name' => 'Child Lock'],
],
'controls' => [
'id' => 84, 'name' => 'CONTROLS (E.G. TOUCH, DIAL )'
]
];
$preparedData = [];
foreach ($data as $key => $value) {
$preparedData[$key] = (count($value) === count($value, COUNT_RECURSIVE))
? [$value]
: $value;
}
$groupedData = [];
foreach ($preparedData as $key => $value) {
$groupedData[$key] = array_column($value, 'name', 'id');
}
var_dump(
$groupedData['child-safety-lock'][652],
$groupedData['child-safety-lock'][336],
$groupedData['controls'][84],
);
If you only have one key that has multiple sub array items, and all those ids are unique, you could just map ids to keys:
<?php
$data =
[
'biscuits' => [
[
'id' => 3,
'name' => 'Digestive'
],
[
'id' => 4,
'name' => 'Rich tea'
]
],
'cake' =>
[
'id' => 5,
'name' => 'Victoria'
]
];
foreach($data as $k => $item) {
if($k == 'biscuits') {
foreach($item as $biscuit) {
$id_key[$biscuit['id']] = $k;
}
}
else {
$id_key[$item['id']] = $k;
}
}
var_export($id_key);
Output:
array (
3 => 'biscuits',
4 => 'biscuits',
5 => 'cake',
)
I created an array based on a mysql table
Array (
[0] => Array ( [id] => 1 [parent_ID] => 0 )
[1] => Array ( [id] => 2 [parent_ID] => 0 )
[2] => Array ( [id] => 3 [parent_ID] => 2 )
[3] => Array ( [id] => 4 [parent_ID] => 2 )
[4] => Array ( [id] => 5 [parent_ID] => 2 )
[5] => Array ( [id] => 6 [parent_ID] => 1 )
[6] => Array ( [id] => 7 [parent_ID] => 1 )
[7] => Array ( [id] => 8 [parent_ID] => 1 )
[8] => Array ( [id] => 9 [parent_ID] => 1 )
I want to create a new array, where the order of the parent_ID is based on the ID. If the parent_ID from an array is “1”, than it needs to be placed directly after the array that has ID “1”. The output of the new array needs to be like this:
Array (
[0] => Array ( [id] => 1 [parent_ID] => 0 )
[1] => Array ( [id] => 6 [parent_ID] => 1 )
[2] => Array ( [id] => 7 [parent_ID] => 1 )
[3] => Array ( [id] => 8 [parent_ID] => 1 )
[4] => Array ( [id] => 9 [parent_ID] => 1 )
[5] => Array ( [id] => 2 [parent_ID] => 0 )
[6] => Array ( [id] => 3 [parent_ID] => 2 )
[7] => Array ( [id] => 4 [parent_ID] => 2 )
[8] => Array ( [id] => 5 [parent_ID] => 2 )
I tried to order my array by using the usort function, but that will only order the parent_ID or the ID column. Is it possible with PHP to sort an array like the example?
As said in my comment to the question your proposed result is bogus...
But here is some simple algorithm constructing such output:
<?php
$input = [
['id' => 1, 'parent_ID' => 0],
['id' => 2, 'parent_ID' => 0],
['id' => 3, 'parent_ID' => 2],
['id' => 4, 'parent_ID' => 2],
['id' => 5, 'parent_ID' => 2],
['id' => 6, 'parent_ID' => 1],
['id' => 7, 'parent_ID' => 1],
['id' => 8, 'parent_ID' => 1],
['id' => 9, 'parent_ID' => 1]
];
$data = [];
$output = [];
array_walk ($input, function($entry) use (&$data) {
$data[$entry['parent_ID']][] = $entry;
});
array_walk ($data[0], function($entry) use ($data, &$output) {
$output[] = $entry;
foreach ($data[$entry['id']] as $child) {
$output[] = $child;
}
});
print_r($output);
The output of executing that obviously is:
Array
(
[0] => Array
(
[id] => 1
[parent_ID] => 0
)
[1] => Array
(
[id] => 6
[parent_ID] => 1
)
[2] => Array
(
[id] => 7
[parent_ID] => 1
)
[3] => Array
(
[id] => 8
[parent_ID] => 1
)
[4] => Array
(
[id] => 9
[parent_ID] => 1
)
[5] => Array
(
[id] => 2
[parent_ID] => 0
)
[6] => Array
(
[id] => 3
[parent_ID] => 2
)
[7] => Array
(
[id] => 4
[parent_ID] => 2
)
[8] => Array
(
[id] => 5
[parent_ID] => 2
)
)
However I would like to make some comments to your situation:
you really should not store a value of 0 for the first elements. They do not have a parent, if I get your situation right, so that value should actually be null, not 0.
you should try to order your data right in the SQL query
you should rethink the overall approach since apparently you have huge issues sorting your data with the given data model. That typically is a sign of a modelling approach that should be reworked.
I am trying to convert a flat array into multidimensional array based on 'parent' and look a lot of examples and get good results but have 1 issue. I am missing last time of the array.
first i created an flat array
$service_arr = array();
foreach( $order_info[0]['service'] as $ordered_service ) {
$s_id = $ordered_service['id'];
$s_name = $ordered_service['name'];
$s_qty = $ordered_service['qty'];
$s_price = $ordered_service['price'];
$s_parent = gp_get_item_parent( $s_id ); // return parent_id of the element.
$service_arr[] = array(
'id' => $s_id,
'name' => $s_name,
'qty' => $s_qty,
'price' => $s_price,
'parent' => $s_parent
);
}
and this return's a flat array
Result:
Array
(
[0] => Array
(
[id] => 29
[name] => Another Facial
[qty] => 1
[price] => 1800
[parent] => 16
)
[1] => Array
(
[id] => 17
[name] => Facial 1
[qty] => 1
[price] => 2000
[parent] => 16
)
[2] => Array
(
[id] => 26
[name] => Addon
[qty] => 1
[price] => 500
[parent] => 17
)
[3] => Array
(
[id] => 39
[name] => Another Addon
[qty] => 1
[price] => 150
[parent] => 17
)
[4] => Array
(
[id] => 18
[name] => Facial 2
[qty] => 1
[price] => 2000
[parent] => 16
)
[5] => Array
(
[id] => 38
[name] => Nice Facial
[qty] => 1
[price] => 3000
[parent] => 16
)
[6] => Array
(
[id] => 21
[name] => Massage 2
[qty] => 1
[price] => 6000
[parent] => 14
)
)
Converting flat into multidimension array:
function create_tree_array( &$list, &$output, $parent_id ) {
if ( ! is_array( $list ) ) {
return;
}
if ( ! is_array( $output ) ) {
return;
}
foreach( $list as $i => $item ) {
if ( $item['parent'] == $parent_id ) {
$item['addon'] = array();
create_tree_array( $list, $item['addon'], $item['id'] );
$output[] = $item;
}
}
}
And using this function like
$services_tree = array();
create_tree_array( $service_arr, $services_tree, $service_arr[0]['parent'] );
Its working but the issue is that its missing last item of array:
[6] => Array (
[id] => 21
[name] => Massage 2
[qty] => 1
[price] => 6000
[parent] => 14
)
Hope you can help me with this. Because I'm trying to reorder them but i need first to make the be at a single level of array. From associative array to single array.
$MY_ASSOC_ARRAY
Array
(
[0] => Array
(
[MAIN_ID] => 1
[ORDER] => 1
[NAME] => Animal
[PARENT_ID] => 0
[childs] => Array
(
[0] => Array
(
[MAIN_ID] => 4
[ORDER] => 4
[NAME] => doggie
[PARENT_ID] => 1
[childs] => Array
(
[0] => Array
(
[MAIN_ID] => 18
[ORDER] => 18
[NAME] => hunting
[PARENT_ID] => 4
[childs] => Array
(
[0] => Array
(
[MAIN_ID] => 21
[ORDER] => 21
[NAME] => setter
[PARENT_ID] => 18
)
[1] => Array
(
[MAIN_ID] => 22
[ORDER] => 22
[NAME] => pointer
[PARENT_ID] => 18
)
)
)
[1] => Array
(
[MAIN_ID] => 19
[ORDER] => 19
[NAME] => companion
[PARENT_ID] => 4
)
)
)
)
)
)
Alright now the array should not be in that multi level (associative) array instead it will look like this:
Array
(
[0] => Array
(
[MAIN_ID] => 1
[ORDER] => 1
[NAME] => Animal
[PARENT_ID] => 0
)
[1] => Array
(
[MAIN_ID] => 4
[ORDER] => 4
[NAME] => doggie
[PARENT_ID] => 1
)
[2] => Array
(
[MAIN_ID] => 18
[ORDER] => 18
[NAME] => hunting
[PARENT_ID] => 4
)
[3] => Array
(
[MAIN_ID] => 21
[ORDER] => 21
[NAME] => setter
[PARENT_ID] => 18
)
[4] => Array
(
[MAIN_ID] => 22
[ORDER] => 22
[NAME] => pointer
[PARENT_ID] => 18
)
[5] => Array
(
[MAIN_ID] => 19
[ORDER] => 19
[NAME] => companion
[PARENT_ID] => 4
)
)
I'm no sure how will that be possible in the most effecient way without using too much memory that will affect the speed with the use of Php Codeigniter. Thanks!
[UPDATE # 1]
here are the code that I have tried but the order is different
foreach($tree as $key => $value) {
$single[] = $value;
}
And this is the output for this failed attemp...
Array
(
[0] => Array
(
[MAIN_ID] => 1
[ORDER] => 1
[NAME] => Animal
[PARENT_ID] => 0
)
[1] => Array
(
[MAIN_ID] => 4
[ORDER] => 4
[NAME] => doggie
[PARENT_ID] => 1
)
[2] => Array
(
[MAIN_ID] => 18
[ORDER] => 18
[NAME] => hunting
[PARENT_ID] => 4
)
[3] => Array
(
[MAIN_ID] => 19
[ORDER] => 19
[NAME] => companion
[PARENT_ID] => 4
)
[4] => Array
(
[MAIN_ID] => 21
[ORDER] => 21
[NAME] => setter
[PARENT_ID] => 18
)
[5] => Array
(
[MAIN_ID] => 22
[ORDER] => 22
[NAME] => pointer
[PARENT_ID] => 18
)
)
The [NAME] => companion should be at the last array not on 4th ([3] => Array)
UPDATE # 2:
Feel bad about the down votes... if this question or problem is not useful on your end
<?php
$array = Array(
0 => Array
(
'MAIN_ID' => 1,
'ORDER' => 1,
'NAME' => 'Animal',
'PARENT_ID' => 0,
'childs' => Array
(
0 => Array
(
'MAIN_ID' => 4,
'ORDER' => 4,
'NAME' => 'doggie',
'PARENT_ID' => 1,
'childs' => Array
(
0 => Array
(
'MAIN_ID' => 18,
'ORDER' => 18,
'NAME' => 'hunting',
'PARENT_ID' => 4,
'childs' => Array
(
0 => Array
(
'MAIN_ID' => 21,
'ORDER' => 21,
'NAME' => 'setter',
'PARENT_ID' => 18,
),
1 => Array
(
'MAIN_ID' => 22,
'ORDER' => 22,
'NAME' => 'pointer',
'PARENT_ID' => 18,
)
)
),
1 => Array
(
'MAIN_ID' => 19,
'ORDER' => 19,
'NAME' => 'companion',
'PARENT_ID' => 4,
)
)
)
)
)
);
$out = [];
$out = generateArray($array, $out);
print_r($out);
function generateArray($in, $out){
foreach($in as $value){
$childs = false;
if(isset($value['childs'])){
$childs = $value['childs'];
unset($value['childs']);
}
$out[] = $value;
if($childs)
$out = generateArray($childs, $out);
}
return $out;
}
?>