Php count rows and division into a group - php

Users create accounts and they are assigned to a group, group limit is set in advance, let's assume 5.
Example: First 5 users has been saved to group_id = 1. Than how to make the 6th user have been saved to the 2nd group?
UserGroups::insert([
'user_id' => $user,
'game_id' => $gameId,
'group_id' => 1
]);
How to make this dynamic for some groups, like group_id = 3..4..5..6 etc ?
Example code:
$groupSize = 2;
$allUserGroups = 4;
if($groupSize < $allUserGroups) {
UserGroups::insert([
'user_id' => $user,
'game_id' => $gameId,
'group_id' => 1
]);
} else {
UserGroups::insert([
'user_id' => $user,
'game_id' => $gameId,
'group_id' => 2
]);
}
This is only work with two groups - how to make this dynamic ?
Thanks guys!

<?php
$arrayUsers=['user1','user2','user3','user4','user5',
'user6','user7','user8','user9','user10',
'user11','user12','user13','user14','user15'];
$group_id=1;
echo'<pre>';
$groupedUser=array_chunk($arrayUsers, 5);
foreach($groupedUser as $data ){
$newArray[$group_id]=$data ;
$group_id++;
}
print_r($newArray);
So let's assume that your users are in the array i created. array_chunk will split them in groups of the number you want. As you said in your question i splitted them in groups of 5. Then to create dynamic groups i just used a counter which i increment by one everytime my array field was full (5 records). In the output you will get a multidimensional array with keys the group_id and values the users.
Array
(
[1] => Array
(
[0] => user1
[1] => user2
[2] => user3
[3] => user4
[4] => user5
)
[2] => Array
(
[0] => user6
[1] => user7
[2] => user8
[3] => user9
[4] => user10
)
[3] => Array
(
[0] => user11
[1] => user12
[2] => user13
[3] => user14
[4] => user15
)
)

if i understand your problem your are looking for this solution :-
$getgroups = UserGroups::select('group_id',DB::raw('count(group_id) as count'))->groupby('group_id')->get();
$getgroups = json_decode(json_encode($getgroups),true);
if(!empty($getgroups)){
end($getgroups);
$key = key($getgroups);
$group = $getgroups[$key];
if($group['count'] <5){
UserGroups::insert([
'user_id' => $user,
'game_id' => $gameId,
'group_id' => $group['group_id']
]);
}else{
$groupvalue = $group['group_id'] +1;
UserGroups::insert([
'user_id' => $user,
'game_id' => $gameId,
'group_id' => $groupvalue
]);
}
}else{
UserGroups::insert([
'user_id' => $user,
'game_id' => $gameId,
'group_id' => 1
]);
}
echo "saved"; die;
I have tested its working perfectly. Good luck for your project :)

Related

PHP - array_push to create a multidimensional array

I am trying to create an array which will have two key/value pairs for each user. I would like to add their user ID as well as their name.
Currently I have this:
<?php
$userArray = array();
foreach ($users as $user) {
array_push($userArray, $user->ID, $user->name);
}
print_r($userArray);
?>
This gives me the following:
Array ([0] => 167 [1] => Bill [2] => 686 [3] => Jim [4] => 279 [5] => Tom)
However, to make it easier to read and work with, I would prefer that it shows user_id and user_name as the keys, rather than just the index. I believe this is what's called a multidimensional array and would look more like this:
Array (
0 => array(
'user_id' => 167,
'user_name' => 'Bill'
),
1 => array(
'user_id' => 686,
'user_name' => 'Jim'
),
2 => array(
'user_id' => 279,
'user_name' => 'Tom'
)
)
My question is how would I build an array like this within my foreach loop?
You just need to create the new array and add it to the $userArray, I use [] instead of array_push() though...
$userArray[] = [ 'user_id' => $user->ID, 'user_name' => $user->name];
you should be pushing a new array, like this :
<?php
$userArray = array();
foreach ($users as $user) {
array_push($userArray, ['user_id' => $user->ID, 'user_id' => $user->name]);
}
print_r($userArray);
?>

getting filtered array from array with condition php

This codes are with Codeigniter framework,
I have below array $csv_array
Array ( [0] => Array ( [location] => X33 [usernumber] => 1 [order] => XX [part_number] => Hi ) [1] => Array ( [location] => X33 [usernumber] => 1 [order] => XX [part_number] => 68730 ) [2] => Array ( [location] => W33 [usernumber] => 2 [order] => YY [part_number] => 68741) [3] => Array ( [location] => W33 [usernumber] => 2 [order] => YY [part_number] => Hello )
My requirements,
create an array for each usernumber(here 2 different user) which contains location, part_number, order and then send email only 2 times, 1 to each user with information of array generated for usernumber,
I tried below step code but i lost in loops!
foreach ($csv_array as $row)
{
$user = $this->admin_model->get_usershipment($row['usernumber']);
$order_data = array();
for ($i=0; $i < count($csv_array); $i++)
{
if($row['usernumber'] == $user->usernumber)
{
//Create some array to send????
$order_data = array();
//Should be something like below, but should contain for usernumber 1 only, and then in 2nd email it should be for usernumber 2 only
//$order_data = array('location' => $row['location'], 'part_number' => $row['part_number'], 'order' => $row['order']);
}
}
$data = array(
'user_firstname' => $user->user_firstname,
'user_email' => $user->user_email,
'order_data' => $order_data);
$subject = 'Hello Update! ';
$message = $this->parser->parse('templates/notification', $data, TRUE);
$this->emailnotification($user->user_email, $subject, $message);
}
One more problem here is that emailnotification fuction will run 4 times, which i want only for 2 time, means to 2 users only,
Any guide how i can achieve this?
Thanks in advance!
There can be many approaches if i understand you correctly. One solution can be (This is just demo use your own sense to modify it):-
foreach($csv_array as $row)
{
$csv_array1[$row['usernumber']][] = $row
}
foreach ($csv_array1 as $key=>$details)
{
$user = $this->admin_model->get_usershipment($key);
$data = array(
'user_firstname' => $user->user_firstname,
'user_email' => $user->user_email,
'order_data' => $details);//$details has 2 arrays for each user
$subject = 'Hello Update! ';
$message = $this->parser->parse('templates/notification', $data, TRUE);
$this->emailnotification($user->user_email, $subject, $message);
}

PHP merging arrays based on specific array key

I have 2 arrays that I want to merge based on a key's value in array 1. In the below example, I want the game_modes put into the games_list based on a key (id) in games_list.
Array 1 which is pulled from a table full of games:
$games_list = array(
0 => array(
'id' => 23,
'name' => 'Call of Duty: Modern Warfare 3'
),
2 => array(
'id' => 1,
'name' => 'Call of Duty: Black Ops'
)
);
Array 2 which is pulled from a table full of game modes:
$game_modes = array(
0 => array(
'id' => 1,
'game_id' => 1,
'description' => 'Capture the Flag'
),
1 => array(
'id' => 2,
'game_id' => 1,
'description => 'Domination'
),
2 => array(
'id' => 3,
'game_id' => 23,
'description' => 'Kill Confirmed'
)
);
I would like the result to be:
$games_list = array(
0 => array(
'id' => 23,
'name' => 'Call of Duty: Modern Warfare 3'
'modes' => array(
array(
'id' => 3,
'game_id' => 23,
'description' => 'Kill Confirmed'
)
)
),
2 => array(
'id' => 1,
'name' => 'Call of Duty: Black Ops'
'modes'=> array(
0 => array(
'id' => 1,
'game_id' => 1,
'description' => 'Capture the Flag'
),
1 => array(
'id' => 2,
'game_id' => 1,
'description => 'Domination'
)
)
)
);
Additional info, the site I'm working on currently has 71 games in its database and each game could have some arbitrary number of game modes.
Now, I could easily do a bunch of for loops and avoid this question all together. As of right now I don't have ton of game modes entered into the database but I keep adding more all the time. Over time doing exponentially more loops all the time will eventually make the page load speed come to a crawl.
I have taken the time to place this data into memcache to make future calls quicker avoiding the loop.
I've never been good with array_map as I don't quite understand how it works or if its even the right route.
Don't you think query level solution would be better?
The lengthy way would be:
// array: $game_modes;
// array: $game_lists;
foreach ($game_modes as $gm=>$modes){
if (isset($modes['game_id'])){
foreach ($game_lists as $gl=>$lists){
if ($lists['id'] == $modes['game_id']){
$game_lists[$gl]['modes'][] = $modes;
//break;
}
}
}
}
Output Category : Summary
$query = 'SELECT
g.id, g.name_name,
group_concat(gm.description) as descriptions
FROM games as g
LEFT JOIN games_modes as gm
ON g.id = gm.game_id
GROUP BY g.id';
Result:
id | name | descriptions
------------------------------------------------------------
1 | Call of Duty: Black Ops | Capture the Flag, Domination
Output Category : Detail
$query = 'SELECT
g.id, g.name_name,
gm.id, gm.description
FROM games as g
LEFT JOIN games_modes as gm
ON g.id = gm.game_id
ORDER BY g.id';
Result:
id | name | id | description
----- --------------------------- ------- ------------------
1 | Call of Duty: Black Ops | 1 | Capture the Flag
1 | Call of Duty: Black Ops | 2 | Domination
Try this to decrease looping
$cachearray = array();
foreach ($game_modes as $gm=>$modes){
if(array_key_exists($modes['game_id'],$cachearray))
{
$cachearray[$modes['game_id']]['modes'][] = $modes;
}
else
foreach ($games_list as $gl=>$lists){
if ($lists['id'] == $modes['game_id']){
$games_list[$gl]['modes'][] = $modes;
$cachearray[$lists['id']] = &$games_list[$gl];
break;
}
}
}
print_r($games_list);
It will be easier if you have $games_list array like this
$games_list = array(
23 => array(
'id' => 23,
'name' => 'Call of Duty: Modern Warfare 3'
),
1 => array(
'id' => 1,
'name' => 'Call of Duty: Black Ops'
)
);
And will more powerfull by using query
If you want to user array map, this code should be possible:
$ids = array_map(function($game) { return $game['id']; }, $games_list);
$id_mapping = array_flip($ids);
foreach($game_modes as $mode) {
if (array_key_exists($mode['game_id'], $id_mapping)) {
$games_list[$id_mapping[$mode['game_id']]]['modes'][] = $mode;
}
}
But I do not know whether this is faster than the two for loops.
try this:
$mode_map = array();
foreach($game_modes as $mode)
{
$game_id = $mode['game_id'];
if(!isset($mode_map[$game_id]))
{
$mode_map[$game_id] = array();
}
$mode_map[$game_id][] = $mode;
}
foreach($games_list as &$game)
{
$game_id = $game['id'];
if(isset($mode_map[$game_id]))
{
$game['modes'] = $mode_map[$game_id];
}
}
print_r($games_list);
result:
Array
(
[0] => Array
(
[id] => 23
[name] => Call of Duty: Modern Warfare 3
[modes] => Array
(
[0] => Array
(
[id] => 3
[game_id] => 23
[description] => Kill Confirmed
)
)
)
[2] => Array
(
[id] => 1
[name] => Call of Duty: Black Ops
[modes] => Array
(
[0] => Array
(
[id] => 1
[game_id] => 1
[description] => Capture the Flag
)
[1] => Array
(
[id] => 2
[game_id] => 1
[description] => Domination
)
)
)
)

Different positions in array

I have an sql query which outputs an array the output looks like this
Array
(
[0] => Array
(
[customer_id] => 7
[language_id] => 1
[variableitem_id] => 13
[name] => QUESTION_HEADLINE
[value] => Bitte geben Sie Ihren Downloadkey ein:
)
[1] => Array
(
[customer_id] => 7
[language_id] => 1
[variableitem_id] => 15
[name] => QUESTION_BUTTON
[value] => Start!
)
[2] => Array
(
[customer_id] => 7
[language_id] => 1
[variableitem_id] => 6
[name] => PAGETITLE
[value] => Steigenberger Hotels and Resorts - Mediathek
)
)
In my controller I get it as
$data['variables_data'] = $this->Home_model->getVariables($customer_id, $language_id);
Now for different ids in the url like for
localhost/home/user/12 and localhost/home/user/14
the positions of the variable differs
for example in my view when I echo
$variable[0]['value']
it gives QUESTION_HEADLINE for one user and PAGE_TITLE for the other .
Is it possible to make them same for all of the user like if I echo
$variable[0]['value']
it should return me QUESTION_HEADLINE every time and for every user
Code for Home model get_variables function
function getVariables($customer_id, $language_id) {
$query = $this->db->query("SELECT customers_idcustomers AS customer_id,
languages_idlanguages AS language_id,
variableitems_idvariableitems AS variableitem_id,
variableitem AS name,
variabletext AS value
FROM variables v
LEFT JOIN variableitems vi ON v.variableitems_idvariableitems = vi.idvariableitems
WHERE v.customers_idcustomers ='" . $customer_id . "'
AND v.languages_idlanguages =" . $language_id
);
$var = $query->result_array();
return $var;
}
Thanks in advance
You can set it explicitly, like
foreach($outArray as $output)
{
$output['name']="Any thing you want";
}
So , as i understand you want to make reduce your output to one dimension. It can be done with MYSQL also. Here php version:
In your controller
$data = $this->Home_model->getVariables($customer_id, $language_id);
$data['variables'] = array(
'customer_id' => $data[0]['customer_id'],
'language_id' => $data[0]['language_id'],
'variableitem_id' => array(),
'name' => array(),
'value' => array()
);
foreach($data as $k => $v) {
$data['variables']['variableitem_id'][] = $v['variableitem_id'];
$data['variables']['name'][] = $v['name'];
$data['variables']['value'][] = $v['value'];
}
And in your view
echo $variables['value'][2].' '.$variables['value'][3];
//do whatever you want

PHP: Array sorting according to another array

I have two arrays with around 50 fields each, one is an array of users, which was obtained from db and looks like this (shortened to only 3 fields)
Array( [0] => Array([id] => 1 [email] => email1#hotmail.com [last_name] => Lastname)
[1] => Array([id] => 2 [email] => email2#hotmail.com [last_name] => Lastname2)
);
My other array, is an array of fields, where key is the name of the field, and value is the field in the users table (shortened as well):
Array([User ID] => id [Last Name] => last_name [Email] => email);
Now, I want to produce an array to compare two users, and after a couple of foreach I got this array:
Array([id] => Array([0] => 1 [1] => 2)
[email] => Array([0] => email1#hotmail.com [1] => email2#hotmail.com)
[last_name] => Array([0] => Lastname [1] => Lastname2)
This last array, as you can see, contains the id for the two users, email for both, etc. which is used to make comparisons. This works, however, you can see that the order does not correspond to the names of the fields array. I would like the third array to be created according to the order of the second array (that is, 1) id, 2) last name, 3) email)
How can that be achieved?
<?php
$newArray = array();
$rows = Array(
Array('id' => 1, 'email' => 'email1#hotmail.com', 'last_name' => 'Lastname'),
Array('id' => 2, 'email' => 'email2#hotmail.com', 'last_name' => 'Lastname2')
);
$fields = Array('User ID' => 'id', 'Last Name' => 'last_name', 'Email' => 'email');
foreach (array_values($fields) as $field) {
$newArray[$field] = array();
foreach ($rows as $singleRow) {
$newArray[$field][] = $singleRow[$field];
}
}
var_dump($newArray);
As you can see, I used another array for ordering.
array_merge(array_fill_keys(array('id', 'lastname', 'email'), null)
, $comparison_arrays
);

Categories