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.
Related
So I've searched for hours but no thread seems to get me to a working solution.
My problem;
I've got 2 arrays. 1 array with the user's roles. And one array with all roles with an specific order.
$roles = Array
(
[0] => Array
(
[id] => 22465
[name] => Rank 1
[position] => 24
[color] => 16711680
)
[1] => Array
(
[id] => 59454
[name] => Rank 2
[position] => 15
[color] => 15844367
)
[2] => Array
(
[id] => 62280
[name] => Rank 3
[position] => 2
[color] => 65494
)
[3] => Array
(
[id] => 67139
[name] => Rank 4
[position] => 10
[color] => 1146986
)
[4] => Array
(
[id] => 75372
[name] => Rank 5
[position] => 25
[color] => 1146986
)
[5] => Array
(
[id] => 75373
[name] => Rank 6
[position] => 18
[color] => 1146986
)
...
)
And I have the user roles array:
$userdata = Array
(
[roles] => Array
(
[0] => 22465
[1] => 59454
[2] => 62280
[3] => 67139
[4] => 75372
[5] => 75373
)
[data] => Array
(
[0] => irrelevant
)
)
I want the user roles array to be sorted to the roles 'position' in the other array.
I think the bottleneck is in the part that the array has to be called with the subarray [roles][position] to get the order to work.
The result should be:
[0] => 75372
[1] => 22465
[2] => 75373
[3] => 59454
[4] => 67139
[5] => 62280
Could you please help me any further?
Thanks in advance!
// First, build a lookup table relating id directly to position
$ranks = [];
foreach($roles as $role) {
$ranks[$role['id']] = $role['position'];
}
var_dump($ranks);
// Now sort the table using the lookup table we just produced
//
usort($userdata['roles'], function($a, $b) use ($ranks){
return $ranks[$b] <=> $ranks[$a];
});
var_dump($userdata);
Content of userdata array after sorting
array (size=2)
'roles' =>
array (size=6)
0 => int 75372
1 => int 22465
2 => int 75373
3 => int 59454
4 => int 67139
5 => int 62280
'data' =>
array (size=1)
0 => string 'irrelevant' (length=10)
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;
}
?>
I have two arrays
First is
Array
(
[0] => Array
(
[image] => Copy1vs.jpg
[title] => V.S Achuthanandhan
[groupId] => 1
[masterId] => 1
[id] => 1
[itemId] => 1
[status] => 1
)
[1] => Array
(
[image] => Copy1pinarayi.jpg
[title] => Pinarayi Vijayan
[groupId] => 1
[masterId] => 2
[id] => 2
[itemId] => 2
[status] => 1
)
[2] => Array
(
[image] => Copy1chandy.jpg
[title] => Oommen Chandy
[groupId] => 1
[masterId] => 3
[id] => 3
[itemId] => 3
[status] => 1
)
)
And Second is
Array
(
[0] => Array
(
[image] => Copy1antony.jpg
[title] => A. K. Antony
[groupId] => 1
[masterId] => 4
[id] => 4
[itemId] => 4
[status] => 1
)
)
How can i combine these two arrays as a single array
like
Array
(
[0] => Array
(
[image] => Copy1vs.jpg
[title] => V.S Achuthanandhan
[groupId] => 1
[masterId] => 1
[id] => 1
[itemId] => 1
[status] => 1
)
[1] => Array
(
[image] => Copy1pinarayi.jpg
[title] => Pinarayi Vijayan
[groupId] => 1
[masterId] => 2
[id] => 2
[itemId] => 2
[status] => 1
)
[2] => Array
(
[image] => Copy1chandy.jpg
[title] => Oommen Chandy
[groupId] => 1
[masterId] => 3
[id] => 3
[itemId] => 3
[status] => 1
)
[3] => Array
(
[image] => Copy1antony.jpg
[title] => A. K. Antony
[groupId] => 1
[masterId] => 4
[id] => 4
[itemId] => 4
[status] => 1
)
)
i tried array_merge method but not working as per my requirement is it possible without using a for loop..?
these arrays gets from databse as
$itemListArray = array();
foreach($subcat as $sc){
$itemList = DB::table('votemasteritems')
->leftjoin('votemaster','votemaster.id','=','votemasteritems.masterId')
->leftjoin('items','items.id','=','votemasteritems.itemId')
->leftjoin('category','category.id','=','items.categoryId')
->select('items.image','votemaster.title','votemaster.groupId','votemaster.id as masterId','votemasteritems.*')
->where('votemaster.groupId',1)
->where('category.Id',$sc->id)
->get();
array_merge($itemListArray, $itemList);
}
Yes, PHP has the array_merge() function: http://php.net/array_merge
Use it like $combinedArray = array_merge($array1, $array2);.
array_merge doesn’t modify the arrays you pass to it. It only returns a new array containing all of the values, so in your example you’d have to replace the original array like:
$itemListArray = array_merge($itemListArray, $itemList);
check this one
foreach($subcat as $sc){
$itemList = DB::table('votemasteritems')
->leftjoin('votemaster','votemaster.id','=','votemasteritems.masterId')
->leftjoin('items','items.id','=','votemasteritems.itemId')
->leftjoin('category','category.id','=','items.categoryId')
->select('items.image','votemaster.title','votemaster.groupId','votemaster.id as masterId','votemasteritems.*')
->where('votemaster.groupId',1)
->where('category.Id',$sc->id)
->get();
$itemListArray[]=$itemList;
}
Try array_merge() function
<?php
$array1 = array("color" => "red", 2, 4);
$array2 = array("a", "b", "color" => "green", "shape" => "trapezoid", 4);
$result = array_merge($array1, $array2);
print_r($result);
?>
In your case, it should be:
$itemListArray = array_merge($itemListArray, $itemList);
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
This question already has answers here:
How to sort an array of arrays in php?
(3 answers)
php - usort or array_multisort?
(3 answers)
Get the first N elements of an array?
(5 answers)
PHP: Any function that return first/last N elements of an array
(2 answers)
Closed 2 years ago.
I have the following array:
Array (
[0] => Array (
[count] => 9
[user_id] => 2
)
[1] => Array (
[count] => 25
[user_id] => 1
)
[2] => Array (
[count] => 20
[user_id] => 3 )
[3] => Array (
[count] => 6
[user_id] => 56 )
[4] => Array (
[count] => 2
[user_id] => 37 )
[5] => Array (
[count] => 1
[user_id] => 0
))
This is just a sample. The actual array will contain many more sub arrays.
I need to be able to obtain the top five values from "count" and store them with their associated "user_id".
The final result needs to look something like this:
Array (
[0] => Array (
[count] => 25
[user_id] => 1
)
[1] => Array (
[count] => 20
[user_id] => 3
)
[2] => Array (
[count] => 9
[user_id] => 2
)
[3] => Array (
[count] => 6
[user_id] => 56
)
[4] => Array (
[count] => 2
[user_id] => 37
)
[5] => Array (
[count] => 1
[user_id] => 0
) )
If this can be done by simply re ordering the array, that is fine.
Thanks!
You're looking for usort and array_slice.
Example:
<?php
$array = array(
array(
'count' => 9,
'user_id' => 2
),
array(
'count' => 25,
'user_id' => 1
),
array(
'count' => 20,
'user_id' => 3
),
array(
'count' => 6,
'user_id' => 56
),
array(
'count' => 2,
'user_id' => 37
),
array(
'count' => 1,
'user_id' => 0
)
);
function usort_callback($a, $b)
{
if ( $a['count'] == $b['count'] )
return 0;
return ( $a['count'] > $b['count'] ) ? -1 : 1;
}
usort($array, 'usort_callback');
$top5 = array_slice($array, 0, 5);
print_r($top5);
Outputs:
Array
(
[0] => Array
(
[count] => 25
[user_id] => 1
)
[1] => Array
(
[count] => 20
[user_id] => 3
)
[2] => Array
(
[count] => 9
[user_id] => 2
)
[3] => Array
(
[count] => 6
[user_id] => 56
)
[4] => Array
(
[count] => 2
[user_id] => 37
)
)
usort($array, function ($a, $b) { return $b['count'] - $a['count']; });
$top5 = array_slice($array, 0, 5);