Where to pass temp array when using recursive function? - php

I'm using a foreach loop inside my recursive function. But I have trouble figuring out where to pass my return statement. I need to return my temp array at some point, but I'm not sure how to do this:
<?php
$patterns = function($array, $temp = array(), $i = 0, $id = 0, $parent = 0) use(&$patterns) {
$return = null;
if(array_key_exists($i, $array)) {
foreach($array[$i] as $set) {
if($parent == $set['id']) {
$data = array(
'id' => $set['id'],
'parent' => $set['parent']
);
array_push($temp, $data);
}
$patterns($array, $temp, $i + 1, $set['id'], $set['parent']);
}
}
};
print_r($patterns($rev_relations));
?>
This is my data:
Array(
[0] => Array(
[0] => Array(
[id] => 60
[parent] => 55
)
[1] => Array(
[id] => 57
[parent] => 54
)
)
[1] => Array(
[0] => Array(
[id] => 61
[parent] => 50
)
[1] => Array(
[id] => 54
[parent] => 49
)
)
[2] => Array(
[0] => Array(
[id] => 49
[parent] => 0
)
)
)

<?php
//pass $temp by reference so outside variable gets populated
$patterns = function($array, &$temp, $i = 0, $id = 0, $parent = 0) use(&$patterns) {
$return = null;
if(array_key_exists($i, $array)) {
foreach($array[$i] as $set) {
if($parent == $set['id']) {
$data = array(
'id' => $set['id'],
'parent' => $set['parent']
);
array_push($temp, $data);
}
$patterns($array, $temp, $i + 1, $set['id'], $set['parent']);
}
}
};
//actuall array is created on temp here
$temp=array();
$patterns($rev_relations,$temp);
?>
wont this work? Never really worked with nameless functions, but this is how i would go about it on a normall recursive function
Ok, take two
<?php
$patterns = function($array, $temp = array(), $i = 0, $id = 0, $parent = 0) use(&$patterns) {
$return = null;
if(array_key_exists($i, $array)) {
foreach($array[$i] as $set) {
if($parent == $set['id']) {
$data = array(
'id' => $set['id'],
'parent' => $set['parent']
);
array_push($temp, $data);
}
return $patterns($array, $temp, $i + 1, $set['id'], $set['parent']);
}
}
else
{
return $temp;
}
};
$patterns($rev_relations);
?>

Related

balance the arrays for each index

<?php
$teams = [0 => ['players' => ['marie'=>2342,
'paul'=>3632,
'vincent'=>2362,
'pierre'=>7823,
'jean'=>9203]
],
1 => ['players' => []
],
2 => ['players' => []
],
3 => ['players' => []
]
];
$all_teams = array_merge($teams[0]['players'],
$teams[1]['players'],
$teams[2]['players'],
$teams[3]['players']);
$result = array_chunk($all_teams, 1, true);
for ($i = 0; $i <= 3; $i++) {
if (isset($result[$i]) && isset($teams[$i])) {
$teams[$i]['players'] = $result[$i];
}
}
//I want a input of array like
$teams = [0 => ['players' => ['marie'=>2342, 'jean'=>9203]
],
1 => ['players' => ['paul'=>3632]
],
2 => ['players' => ['vincent'=>2362]
],
3 => ['players' => ['pierre'=>7823]
]
];
Hello, I want to add each player on each team to balance the arrays;
the problem with my code, it puts it in the mess and 'jean' does not count in the array and i want the last element to be added too. and find a better way to balance the tables for each incoming element.
You can do something like:
$teams = [0 => ['players' => ['marie'=>2342,'paul'=>3632,'vincent'=>2362,'pierre'=>7823,'jean'=>9203]],
1 => ['players' => []],
2 => ['players' => []],
3 => ['players' => []]
];
//Get all players and put them into a single array
$players = array_reduce(array_column( $teams, 'players' ),'array_merge',array());
$teamCount = count($teams);
//Clear all Teams
foreach($teams as $key => $team) {
$teams[$key]['players'] = array();
}
//Assign the playes to the team using mod
foreach(array_keys($players) as $key => $player ) {
$teams[ $key % $teamCount ]['players'][$player] = $players[$player];
}
This will result to:
Array
(
[0] => Array
(
[players] => Array
(
[marie] => 2342
[jean] => 9203
)
)
[1] => Array
(
[players] => Array
(
[paul] => 3632
)
)
[2] => Array
(
[players] => Array
(
[vincent] => 2362
)
)
[3] => Array
(
[players] => Array
(
[pierre] => 7823
)
)
)
Here is a solution. It counts total players and then redistributes according to how many players you want on a team.
function balanceTeams($teams, $playersPerTeam, $shuffle = NULL){
//Get total players in array
$playerCount = 0;
foreach($teams as $team){
foreach($team['players'] as $player=>$id){
$players[] = array('name' => $player, 'id'=>$id);
}
}
$playerCount = count($players);
if($shuffle){
shuffle($players);
}
//Make your new array
$count = 0;
$team = 0;
for($i = 0; $i < $playerCount; $i += $playersPerTeam){
for($j = 0; $j < $playersPerTeam; $j++){
if($players[$count]['id']){
$results[$team]['players'][$players[$count]['name']] = $players[$count]['id'];
}else {
break;
}
$count++;
}
$team++;
}
return $results;
}
How to use:
$teams = [0 => ['players' => ['marie'=>2342,
'paul'=>3632,
'vincent'=>2362,
'pierre'=>7823,
'jean'=>9203]
],
1 => ['players' => []
],
2 => ['players' => []
],
3 => ['players' => []
]
];
$playersPerTeam = 2;
$shuffle = NULL; //Set to 1 to shuffle.
$results = balanceTeams($teams, $playersPerTeam, $shuffle);
print_r($results);
Outputs:
Array
(
[0] => Array
(
[players] => Array
(
[marie] => 2342
[paul] => 3632
)
)
[1] => Array
(
[players] => Array
(
[vincent] => 2362
[pierre] => 7823
)
)
[2] => Array
(
[players] => Array
(
[jean] => 9203
)
)
)
function:
function mixPlayers($teams)
{
$r = [];
array_walk_recursive($teams, function ($v, $k) use (&$r) {
if (!is_array($v)) {
$r[] = [$k => $v];
}
});
return $r;
}
function assign($players, $need)
{
$res = [];
for ($i = 0; $i < count($players); $i++) {
$index = $i % $need;
$res[$index]['players'] = array_merge(
isset($res[$index]['players']) ? $res[$index]['players'] : [],
$players[$i]
);
}
return $res;
}
usage:
$res = assign( mixPlayers($teams) , 4);
var_export($res);

count the duplicate “usuario_cidade” in multi-dimensional

please help me with a code. I have this multi-dimensional array and need to count the value of usuario_cidade case its same value like this:
array 52 = (2) Cidade_1, (2) Cidade_2, (1) Cidade_3
Array
(
[52] => Array
(
[0] => stdClass Object
(
[funcionario_id] => 52
[usuario_cidade] => Cidade_1
)
[1] => stdClass Object
(
[funcionario_id] => 52
[usuario_cidade] => Cidade_1
)
[2] => stdClass Object
(
[funcionario_id] => 52
[usuario_cidade] => Cidade_2
)
[3] => stdClass Object
(
[funcionario_id] => 52
[usuario_cidade] => Cidade_3
)
[4] => stdClass Object
(
[funcionario_id] => 52
[usuario_cidade] => Cidade_2
)
)
)
Try this code:
//Create object array format as per question scenario for testing...
$arrObject1 = new stdClass();
$arrObject1->funcionario_id = '52';
$arrObject1->usuario_cidade = 'Cidade_1';
$arrObject2 = new stdClass();
$arrObject2->funcionario_id = '52';
$arrObject2->usuario_cidade = 'Cidade_1';
$arrObject3 = new stdClass();
$arrObject3->funcionario_id = '52';
$arrObject3->usuario_cidade = 'Cidade_2';
$arrObject4 = new stdClass();
$arrObject4->funcionario_id = '52';
$arrObject4->usuario_cidade = 'Cidade_3';
$arrObject5 = new stdClass();
$arrObject5->funcionario_id = '52';
$arrObject5->usuario_cidade = 'Cidade_2';
//Finalize array...
$varArray = array('52' => array(
$arrObject1, $arrObject2, $arrObject3, $arrObject4, $arrObject5
));
$arrResult = array();
//Loop until main array...
foreach($varArray AS $arrKey => $arrObjVal){
//Loop for object values...
foreach($arrObjVal AS $ocjKey => $objVal){
//Check for specific key(i.e. value of usuario_cidade) exist into result array...
if(array_key_exists($objVal->usuario_cidade, $arrResult)){
//Increment value if exist...
$arrResult[$objVal->usuario_cidade] = $arrResult[$objVal->usuario_cidade] + 1;
}
else {
//Initialize value of result array...
$arrResult[$objVal->usuario_cidade] = 1;
}
}
}
print('<pre>');
print_r($arrResult);
print('</pre>');
This will give result:
[Cidade_1] => 2
[Cidade_2] => 2
[Cidade_3] => 1
Hope this help you!
Try this..
$your_array = array();
$usuario_cidade = array();
foreach ($your_array as $key => $values){
foreach($values as $value){
$usuario_cidade[$key][$value->usuario_cidade]=isset($usuario_cidade[$key][$value->usuario_cidade]) ? $usuario_cidade[$key][$value->usuario_cidade] : '0' + 1;
}
}
print_r($usuario_cidade);
Hey kindly check this code it is given the same answer as the conditions are given.
$arr = array();
$arr2 = array('funcionario_id' => 52,'usuario_cidade' => 'Cidade_1' );
$arr3 = array('funcionario_id' => 52,'usuario_cidade' => 'Cidade_1' );
$arr4 = array('funcionario_id' => 52,'usuario_cidade' => 'Cidade_2' );
$arr5 = array('funcionario_id' => 52,'usuario_cidade' => 'Cidade_3' );
$arr6 = array('funcionario_id' => 52,'usuario_cidade' => 'Cidade_2' );
$arr = [$arr2,$arr3,$arr4,$arr5,$arr6];
$cidaed = array('Cidade_1' => 0, 'Cidade_2' => 0 , 'Cidade_3' => 0 );
$count = 0;
//echo var_dump($arr);
foreach ($arr as $key => $value) {
foreach ($value as $keys => $values) {
if($keys == 'usuario_cidade')
{
$cidaed[$values] += 1;
}
}
}
echo var_dump($cidaed);
The answer for above will be.
array(3) { ["Cidade_1"]=> int(2) ["Cidade_2"]=> int(2) ["Cidade_3"]=> int(1) }
Can you please check this.
$main_array[52] = array(
0 => array(
'funcionario_id' => 52,
'usuario_cidade' => 'Cidade_1'
),
1 => array(
'funcionario_id' => 52,
'usuario_cidade' => 'Cidade_1'
),
2 => array(
'funcionario_id' => 52,
'usuario_cidade' => 'Cidade_2'
),
3 => array(
'funcionario_id' => 52,
'usuario_cidade' => 'Cidade_3'
),
4 => array(
'funcionario_id' => 52,
'usuario_cidade' => 'Cidade_2'
)
);
$check_array = array();
$count_array = array();
foreach ($main_array as $main){
foreach($main as $data){
if(in_array($data['usuario_cidade'], $check_array)){
$count_array[$data['usuario_cidade']] = $count_array[$data['usuario_cidade']] + 1;
}else{
array_push($check_array,$data['usuario_cidade']);
$count_array[$data['usuario_cidade']] = 1;
}
}
}
foreach($count_array as $key => $value){
echo $key.'='.$value.'<br />';
}
echo "<pre>"; print_r($count_array);

php tree ul li hierarchy menu from array

we have this array from mysqli query output :
$items = Array
(
Array
(
'id' => 1,
'title' => 'menu1',
'parent_id' => 0
),
Array
(
'id' => 2,
'title' => 'submenu1-1',
'parent_id' => 1
),
Array
(
'id' => 3,
'title' => 'submenu1-2',
'parent_id' => 1
),
Array
(
'id' => 4,
'title' => 'menu2',
'parent_id' => 0
),
Array
(
'id' => 5,
'title' => 'submenu2-1',
'parent_id' => 4
)
);
and we need this html output with php :
<ul>
<li><a>menu1</a>
<ul>
<li><a>submenu1-1</a></li>
<li><a>submenu1-2</a></li>
</ul>
</li>
<li><a>menu2</a>
<ul>
<li><a>submenu2-1</a></li>
</ul>
</li>
</ul>
can anyone help me ?
Probably this is very easy but I have tried everything already without success !!
finally i found answer like this:
function generateTreeMenu($datas, $parent = 0, $limit=0){
if($limit > 1000) return '';
$tree = '';
$tree = '<ul>';
for($i=0, $ni=count($datas); $i < $ni; $i++){
if($datas[$i]['parent_id'] == $parent){
$tree .= '<li><a>';
$tree .= $datas[$i]['title'].'</a>';
$tree .= generatePageTree($datas, $datas[$i]['id'], $limit++);
$tree .= '</li>';
}
}
$tree .= '</ul>';
return $tree;
}
echo generateTreeMenu($items);
//index elements by id
foreach ($items as $item) {
$item['subs'] = array();
$indexedItems[$item['id']] = (object) $item;
}
//assign to parent
$topLevel = array();
foreach ($indexedItems as $item) {
if ($item->parent_id == 0) {
$topLevel[] = $item;
} else {
$indexedItems[$item->parent_id]->subs[] = $item;
}
}
//recursive function
function renderMenu($items) {
$render = '<ul>';
foreach ($items as $item) {
$render .= '<li>' . $item->title;
if (!empty($item->subs)) {
$render .= renderMenu($item->subs);
}
$render .= '</li>';
}
return $render . '</ul>';
}
echo renderMenu($topLevel);
The problem here is just the structure of the array, so first you can convert the array to a more suitable structure, then you can draw your list easily.
Here is a function to convert the array:
function makeTree( $rst, $level, &$tree )
{
for ( $i=0, $n=count($rst); $i < $n; $i++ )
{
if ( $rst[$i]['parent_id'] == $level )
{
$branch = array(
'id' => $rst[$i]['id'],
'title' => $rst[$i]['title'],
'children' => array()
);
makeTree( $rst, $rst[$i]['id'], $branch['children'] );
$tree[] = $branch;
}
}
}
Mode of use:
$tree = array();
makeTree( $originalArray, 0, $tree );
At the end, you will have a new array in $tree structured as shown below, which you can easily draw in your view.
Array
(
[0] => Array
(
[id] => 1
[title] => menu1
[children] => Array
(
[0] => Array
(
[id] => 2
[title] => submenu1-1
[children] => Array
(
)
)
[1] => Array
(
[id] => 3
[title] => submenu1-2
[children] => Array
(
)
)
)
)
[1] => Array
(
[id] => 4
[title] => menu2
[children] => Array
(
[0] => Array
(
[id] => 5
[title] => submenu2-1
[children] => Array
(
)
)
)
)
)
Try this
$node = array();
foreach ($items as $item) {
if ($item['parent_id'] == 0) {
$node[$item['id']][$item['id']] = $item['title'];
} else {
$node[$item['parent_id']][$item['id']] = $item['title'];
}
}
$result = array();
foreach ($node as $key => $value) {
$result[$value[$key]] = array_diff($value, array($key => $value[$key]));
}

PHP - split array from query

I am using PHP and I have array from query
Array
(
[0] => stdClass Object
(
[question_id] => 13
[is_break] => 0
)
[1] => stdClass Object
(
[question_id] => 14
[is_break] => 1
)
[2] => stdClass Object
(
[question_id] => 15
[is_break] => 0
)
[3] => stdClass Object
(
[question_id] => 16
[is_break] => 1
)
[4] => stdClass Object
(
[question_id] => 17
[is_break] => 1
)
)
How to split (grouping) by is_break = 1 so i have question_id (13,14)(15,16)(17)
A simple and naive solution might look something like this:
var original = /* your original array, the one you posted */;
var result = [];
var tmp = [];
$.each(original, function(idx, obj) {
tmp.push(obj.question_id);
if(obj.is_break == 1) {
result.push(tmp);
tmp = [];
}
});
console.log(result); // returns array of array
HTH
EDIT: In PHP, it may look something like this (I am not too well-versed in PHP):
var $original = /* your original array, the one you posted */;
var $result = [];
var $tmp = [];
foreach($original as $obj) {
$tmp.push($obj.question_id); /* or could be $obj['question_id'] */
if($obj.is_break == 1) { /* or could be $obj['is_break'] */
$result.push($tmp);
$tmp = [];
}
});
Here's solution
$data = {your data};
$result = array();
$i = 0;
foreach($data as $k => $item) {
if ($item->is_break) {
$result[] = array_slice($data, $i, $k);
}
$i = $k;
}
print_r($result);
Try this:
<?php
$inputArr = Array
(
Array("question_id" => 13, "is_break" => 0),
Array("question_id" => 14, "is_break" => 1),
Array("question_id" => 15, "is_break" => 0),
Array("question_id" => 16, "is_break" => 1),
Array("question_id" => 17, "is_break" => 1)
);
$result = array();
$tmp = array();
foreach ($inputArr as $obj) {
//$tmp . push($obj . question_id); /* or could be $obj['question_id'] */
array_push($tmp, $obj['question_id']);
if ($obj['is_break'] == 1) { /* or could be $obj['is_break'] */
//$result . push($tmp);
array_push($result, $tmp);
$tmp = array();
}
}
var_dump($result);
?>
Thanks

PHP: reorder array to show hierarchy

How can I turn the first array in to the second one? The goal is to create an array that shows the hierarchy, based on location_id and parent_id. Each location_name should be in an array of which the key is its parent_id.
Ignore the values I gave to location_name. No value for parent_id == NULL, these are the top level items.
First array:
Array
(
[0] => stdClass Object
(
[location_id] => 1
[location_name] => Town 1
[parent_id] =>
)
[1] => stdClass Object
(
[location_id] => 2
[location_name] => Town 1.1
[parent_id] =>
)
[2] => stdClass Object
(
[location_id] => 3
[location_name] => Town 1.2
[parent_id] => 1
)
[3] => stdClass Object
(
[location_id] => 4
[location_name] => Town 1.3
[parent_id] => 1
)
[4] => stdClass Object
(
[location_id] => 5
[location_name] => town 1.1.1
[parent_id] => 2
)
[5] => stdClass Object
(
[location_id] => 6
[location_name] => Town 1.1.2
[parent_id] => 3
)
);
Resulting array should be:
Array(
'Town 1' = array(
'town 1.2',
'town 1.3' = array(
'town 1.1.2'
)
),
'Town 2' = array(
'town 1.1.1'
)
);
EDIT: working solution based on Rijk's answer
function _order_locs($parent, $array)
{
$return = array();
foreach ( $array as $town )
{
if ( $town->parent_id == $parent )
{
$set = $this->_order_locs( $town->location_id, $array );
if( $this->_menu_is_parent($town->location_id, $array) ) $return[$town->location_name] = $set;
else $return[] = $town->location_name;
}
}
return $return;
}
function _menu_is_parent($id, $array)
{
foreach( $array as $a )
{
if( $a->parent_id == $id ) return TRUE;
}
}
You have to loop through it, using a recursive function (one that calls itself):
function getChilds( $parent, $array ) {
$return = array();
foreach ( $array as $town ) {
if ( $town['location_id'] == $parent ) {
$return[] = array(
'name' => $town['location_name'],
'childs' => getChilds( $town['location_id'], $array )
);
}
}
return $return;
}
$towns_tree = getChilds( 0, $towns );
Might not work right off the bat, but that gives you a nice oppurtunity to play with the code and get familiar with this concept ;)
Here is some code that will more or less do what you need. You will have to tweak it to your liking.
<?php
Class Node {
public $id;
public $parent_id;
public $value;
public $children;
public $depth;
function __construct($id, $parent_id, $value) {
$this->id = $id;
$this->parent_id = $parent_id;
$this->value = $value;
$this->children = array();
$this->depth = 0;
}
function add_child(Node $new_child) {
if ($new_child->parent_id == $this->id) {
$this->children[$new_child->id] = $new_child;
$this->children[$new_child->id]->depth = $this->depth + 1;
} else {
foreach ($this->children as $child) {
$child->add_child($new_child);
}
}
}
function to_array() {
if (count($this->children) > 0) {
$arr = array();
foreach ($this->children as $child) {
array_push($arr, $child->to_array());
}
return array($this->value => $arr);
} else {
return $this->value;
}
}
function str() {
echo str_repeat(" ", $this->depth) . $this->value . "\n";
foreach ($this->children as $child) {
$child->str();
}
}
}
?>
Here is some sample code to test it with:
<?php
$arr = Array(
array('location_id' => 1,
'location_name' => 'Town 1',
'parent_id' => 0),
array('location_id' => 2,
'location_name' => 'Town 1.1',
'parent_id' => 0),
array('location_id' => 3,
'location_name' => 'Town 1.2',
'parent_id' => 1),
array('location_id' => 4,
'location_name' => 'Town 1.3',
'parent_id' => 1),
array('location_id' => 5,
'location_name' => 'Town 1.1.1',
'parent_id' => 2),
array('location_id' => 6,
'location_name' => 'Town 1.1.2',
'parent_id' => 3)
);
$root = new Node(0, 0, 'root');
foreach ($arr as $item) {
$node = new Node($item['location_id'],
$item['parent_id'],
$item['location_name']);
$root->add_child($node);
}
$tree = $root->to_array();
$tree = $tree['root'];
var_dump($tree);
?>

Categories