Counting entries in sub/subarray - php

I am working on a chat.
I have an array that contains the info regarding the room
(in the example below, 2 rooms (the lounge, the beach)).
I have an issue when I have an empty room (in the example the beach), as it contains by default no user, (which is a Null user).
$roomNusers=Array (
[The Lounge] =>
Array ( [id] => 1
[privacy] => public
[users] => Array
[QUICHE POIREAU] => Array
[smiley] => smi_smile.gif
[name] => QUICHE POIREAU
[state] => NULL
[id] => 1 )
[JOHN DOE] => Array
[smiley] => smi_smile.gif
[name] => Joe FRANC
[state] =>
[id] => 40 )
[The Beach] => Array
[id] => 2
[privacy] => public
[users] => Array
[Null] => Array
[smiley] => Null
[name] => Null
[state] => Null
[id] => Null
I am trying to count, in my array, the number of users currently present in the room.
Looking around Stack Overflow, I managed to find the solution I wanted:
foreach($roomNusers as $room => $value)
{
echo $room.' user count:'.count($room['users'])
}
This output:
The lounge user count: 2
The beach user count: 1
My issue is that it counts the user [null] in the beach.
How can I count the number of users not null per room?
I thought of a workaround with something similar to:
$countperroom= .count($room['users'])-1;
if(isset(end([$room]['users']))){$countuser+1;}
In this, the last user is empty, I do not add an user, but I do not know how to write this.

Rather than counting the number of values in $room['users'], you could count the number of keys after filtering them to remove empty keys:
foreach ($rooms as $name => $room) {
$users = count(array_filter(array_keys($room['users'])));
echo "$name: $users users\n";
}
Output (for your sample data):
The Lounge: 2 users
The Beach: 0 users
Demo on 3v4l.org

Related

Get session values with the same index tag and select the bigger int value

I have a session variable called $_SESSION["shopping_cart"] which saves an array formed by user defined selections on a web page (meaning: products, codes, prices, descriptions and number of active months).
The array will look something like "Array => Array1["xxx"]=> ['product'] = "xxx", ['detail'] = "xxxxx", ['price'] = "xxx", ['envios'] = "x", Array2 => ...... and goes on. Now, SOME of the arrays in there will have an index ['envios'] = "x" and some of them won't. This specific index is always an INT value between 1-12. I need to select all of the values with a index ['envios'] and then save the bigger one of them in a separated variable $corval.
Is there any way to do that?
I found several session functions as session_search() or session_value() BUT all of them will return the value of the index when the input is equal to some array value. And I need to do it the other way around.
Long story short, I need to get all the values for the index ['envios'] inside the session array and save only the bigger of them into a different variable in php. If there is no ['envios'] index the the variable will be equal to 1.
This is the actual array data:
Array ( [BTWL001] => Array ( [name] => P�lulas Winky Lux [code] => BTWL001 [price] => 95.00 [quantity] => 1 [stock] => 8 [image] => /bubale/img/productimg/set5winki.jpg ) [PB001] =>
Array ( [name] => BOLSINHA UNICA [code] => PB001 [price] => 130.00 [quantity] => 1 [stock] => 9999 [image] => /bubale/img/1month.png [envios] => 1 ) [PB003] =>
Array ( [name] => PLANO TRIMESTRAL [code] => PB003 [price] => 300.00 [quantity] => 1 [stock] => 9999 [image] => /bubale/img/3month.png [envios] => 3 ) [PB012] =>
Array ( [name] => PLANO ANUAL [code] => PB012 [price] => 1080.00 [quantity] => 1 [stock] => 9999 [image] => /bubale/img/12month.png [envios] => 12 ) )
Note that there are 3 arrays with the index tag ['envios']. This array is stored in a session so I need to get only those "['envios']" values.
well, after a lot of research I found a solution to this problem, so for those in search of something like this, here we go:
$col = $_SESSION['your session variable'];
$env = array_column($col, 'name of the index you need to extract');
// here the $env will have a new array with only the values identified with the index you looked up for) //
$final = max($env);
//you saved the maximum value of the array//

Change default numeric associative array keys to "number" only without affecting array values

I have a form at http://97.74.37.64/ (visit it first) . It has only one textarea where visitor can fill upto 15000 number of mobile numbers. after submit it should be converted into an array (This one I have done).
Now, this array is like this below..
Array ( [0] => 9810000000 [1] => 9810000001 [2] => 9810000002 [3] => 9810000003 [4] => 9810000004 [5] => 9810000005 [6] => 9810000006 [7] => 9810000007
and so on..
Now, I want to change the key of the array to string "number" so it should be like
Array ( [number] => 9810000000 [number] => 9810000001 [number] => 9810000002 [number] => 9810000003 [number] => 9810000004 [number] => 9810000005 [number] => 9810000006 [number] => 9810000007
I want to do the above mentioned thing. Because I want to insert the mobile numbers into the MySQL table (one mobile number each row). This is the multiple insertion in MySQL table. My table name is srchlist with 2 fields id(its auto_increment & we don't need to mention or insert it) and number for which I am making array keys as number. So finally it should be inserted like below
id | number
---------------
1 9810000000
2 9810000001
3 9810000002
and so on entire array values should be inserted..
What about just organizing these values into an array of arrays? That way you can bulk insert them into your table or insert them as part of a loop if need be:
array(
array("number" => 1), array("number" => 2), array("number" => 3)
)
You can do something like this:
Controller:
// Array ( [0] => 9810000000 [1] => 9810000001 [2] => 9810000002 [3] => 9810000003 [4] => 9810000004 [5] => 9810000005 [6] => 9810000006 [7] => 9810000007)
$number = array('9810000000','9810000001','9810000002','9810000003',,'9810000004','9810000005','9810000006','9810000007');
foreach($number as $row)
{
$number1[]['number'] = $row;
}
$this->M_admin->numbers($number1); //call modal function
Modal:
function numbers($number)
{
// insert into db as batch
$this->db->insert_batch('numbers', $number);
}

How to search a multidimensional array to return multiple keys

I've got a multidimensional array written in php that holds an array of arrays. I've read a lot about how to search this, but it seems most solutions either:
A. require you have unique values for the keys, such as a product id
or
B. are satisfied with returning multiple results in an array
I am looking to search the array given the round number (which is the array number of the highest/first level array), and a player name (which will be the value of either the key player 1 or player 2).
The array looks something like this:
Array (
[0] => Array ( )
[8] => Array (
[1] => Array (
[Match] => 1
[Player1seed] => (Q)
[Player1name] => Mahut
[Player2seed] => (2)
[Player2name] => Goffin
[Matchscore] => 7-6(1), 6-1
[Round] => Finals
)
)
[7] => Array (
[1] => Array (
[Match] => 1
[Player1seed] => (2)
[Player1name] => Goffin
[Player2seed] =>
[Player2name] => Muller
[Matchscore] => 7-6(4), 6-4
[Round] => Semi-Finals
)
[2] => Array
(
[Match] => 2
[Player1seed] => (Q)
[Player1name] => Mahut
[Player2seed] => (WC)
[Player2name] => Haase
[Matchscore] => 5-7, 6-3, 6-4
[Round] => Semi-Finals
)
)
etc.
Essentially, I need to be able to search specifically one subset such as array[7] and be returned the results that contains either player1 or player2 as a name, say Goffin.
But I don't want it to return results from other tournament rounds such as array[8] or array[6] where either player is Goffin.
I can't seem to find this solution anywhere. Am I setting up my array incorrectly? Or expecting database functions from a lesser data set?
Any help would be appreciated.
It's not exactly the way I wanted to solve the problem, but I was able to get the results I wanted by running a loop after identifying the specific round number:
$r = $roundnumber;
foreach( $matchesarray[$r] AS $key=>$data ){
$winnerseed=$data['Player1seed'];
$winnername=$data['Player1name'];
$loserseed=$data['Player2seed'];
$losername=$data['Player2name'];
$matchurl=$data['Matchurl'];
$score=$data['Matchscore'];
if ($p1name == $winnername || $p2name == $losername){
$winner=$p1;
}
else if ($p2name == $winnername || $p1name == $losername){
$winner=$p2;
}
}

Formatting an array to order by specified unix timestamp in PHP

I have an array which has a timestamp consistently on [3] ( an example of the array data below)
I would like the array to be sorted using the timestamp. I've seen a few stackoverflow posts that apparently do this using two methods, array_multisort() and usort() but I've been unable to replicate either.
Here is what I've tried based on my own code:
Attempt 1 - I pass the array to usort, then attempt to take it apart with the foreach. Applying this method definitely changes the order of the results, but the dates seems to be no specific order (ascending, descending).
function sortArray($a1, $a2){
if ($a1[3] == $a2[3]) return 0;
return ($a1[3] > $a2[3]) ? -1 : 1;
}
usort($the_array, "sortArray");
foreach($the_array as $sh) {
$uid = $sh['uid'];
$username = $sh['username'];
$datetime = $sh['datetime'];
$type = $sh['type'];
echo "<p> $uid , $username, $datetime, $type </p>";
}
Attempt 2 - tried using array_multisor() which again gives me results in a different order but I don't understand what it is sorting by exactly.
foreach ($the_array as $key => $node) {
$timestamps[$key] = $node[3];
}
array_multisort($timestamps, SORT_ASC, $the_array);
//process the array with a foreach to show results
My theory here is that it isn't properly processing the unix timestamp and I'm not sure what I can do about that. Is it smart to take out all the characters of the timestamp so it is a simple line of numbers ( 2014-01-02 03:02:12 becomes 20140102030212 )? Or is there another way to process it with the timestamp in it's current form?
Here is an example of the data in the array:
Array
(
[0] => Array
(
[uid] => 20013
[0] => 20013
[username] => myhipswontlie
[1] => myhipswontlie
[rating] => 4.00
[2] => 4.00
[datetime] => 2014-01-27 23:40:56
[3] => 2014-01-27 23:40:56
[type] => rated
[4] => rated
)
[1] => Array
(
[uid] => 20025
[0] => 20025
[username] => brasilchika
[1] => brasilchika
[rating] => 4.00
[2] => 4.00
[datetime] => 2014-01-02 03:02:12
[3] => 2014-01-02 03:02:12
[type] => rated
[4] => rated
)
[2] => Array
(
[uid] => 10002
[0] => 10002
[username] => crtten
[1] => crtten
[datetime] => 2014-01-25 01:33:34
[2] => 2014-01-25 01:33:34
[type] => visits
[3] => visits
)
)
Your issue is your numeric keys don't seem to match up in your arrays. Sometimes the datetime is found in the 3rd key, sometime it is found in the second key (which is odd considering they look like they come from mysql_fetch_array() which will make uniform arrays).
To solve this you should use the associative array key instead:
function sortArray($a1, $a2){
if ($a1['datetime'] == $a2['datetime']) return 0;
return ($a1['datetime'] > $a2['datetime']) ? -1 : 1;
}
usort($the_array, "sortArray");

cakephp - sorting by a second level association in paginate

I am playing around with a quotes database relating to a ski trip I run. I am trying to list the quotes, but sort by the person who said the quote, and am struggling to get the paginate helper to let me do this.
I have four relevant tables.
quotes, trips, people and attendances. Attendances is essentially a join table for people and trips.
Relationships are as follows;
Attendance belongsTo Person hasMany Attendance
Attendance belongsTo Trip hasMany Attendance
Attendance hasMany Quote belongs to Attendance
In the QuotesController I use containable to retrieve the fields from Quote, along with the associated Attendance, and the fields from the Trip and Person associated with that Attendance.
function index() {
$this->Quote->recursive = 0;
$this->paginate['Quote'] = array(
'contain' => array('Attendance.Person', 'Attendance.Trip'));
$this->set('quotes', $this->paginate());
}
This seems to work fine, and in the view, I can echo out
foreach ($quotes as $quote) {
echo $quote['Attendance']['Person']['first_name'];
}
without any problem.
What I cannot get to work is accessing/using the same variable as a sort field in paginate
echo $this->Paginator->sort('Name', 'Attendance.Person.first_name');
or
echo $this->Paginator->sort('Location', 'Attendance.Trip.location');
Does not work. It appears to sort by something, but I'm not sure what.
The $quotes array I am passing looks like this;
Array
(
[0] => Array
(
[Quote] => Array
(
[id] => 1
[attendance_id] => 15
[quote_text] => Hello
)
[Attendance] => Array
(
[id] => 15
[person_id] => 2
[trip_id] => 7
[Person] => Array
(
[id] => 2
[first_name] => John
[last_name] => Smith
)
[Trip] => Array
(
[id] => 7
[location] => La Plagne
[year] => 2000
[modified] =>
)
)
)
I would be immensely grateful if someone could suggest how I might be able to sort by the the first_name of the Person associated with the Quote. I suspect my syntax is wrong, but I have not been able to find the answer. Is it not possible to sort by a second level association in this way?
I am pretty much brand new with cakephp so please be gentle.
Thanks very much in advance.
I've had the similar problem awhile back. Not with sort though. Try putting the associated table in another array.
echo $this->Paginator->sort('Name', 'Attendance.Person.first_name');
change to:
echo $this->Paginator->sort('Name', array('Attendance' => 'Person.first_name'));
Hope this helps
i'm also looking for help with this.
so far i've found that you can sort multi level associations in controller's pagination options after using the linkable plugin https://github.com/Terr/linkable.
but it breaks down when you try to sort form the paginator in the view. i'm using a controller for magazine clippings. each clipping belongs to an issue and each issue belongs to a publication.
$this->paginate = array(
"recursive"=>0,
"link"=>array("Issue"=>array("Publication")),
"order"=>array("Publication.name"=>"ASC",
"limit"=>10);
after debugging $this->Paginator->params->paging->Clipping in the view, you can see that the sort is described in two separate places, "defaults" and "options". the sort info needs to be present in both for it to work in the view.
here is after setting order in controller:
[Clipping] => Array
(
[page] => 1
[current] => 10
[count] => 6685
[prevPage] =>
[nextPage] => 1
[pageCount] => 669
[defaults] => Array
(
[limit] => 10
[step] => 1
[recursive] => 0
[link] => Array
(
[Issue] => Array
(
[0] => Publication
)
)
[order] => Array
(
[Publication.name] => ASC
)
[conditions] => Array
(
)
)
[options] => Array
(
[page] => 1
[limit] => 10
[recursive] => 0
[link] => Array
(
[Issue] => Array
(
[0] => Publication
)
)
[order] => Array
(
[Publication.name] => ASC
)
[conditions] => Array
(
)
)
)
and here is after using $this->Paginator->sort("Publication","Publication.name");.
notice the options array is empty.
[Clipping] => Array
(
[page] => 1
[current] => 10
[count] => 6685
[prevPage] =>
[nextPage] => 1
[pageCount] => 669
[defaults] => Array
(
[limit] => 10
[step] => 1
[recursive] => 0
[link] => Array
(
[Issue] => Array
(
[0] => Publication
)
)
[order] => Array
(
[Publication.name] => DESC
)
[conditions] => Array
(
)
)
[options] => Array
(
[page] => 1
[limit] => 10
[recursive] => 0
[link] => Array
(
[Issue] => Array
(
[0] => Publication
)
)
[order] => Array
(
)
[conditions] => Array
(
)
)
does one really need to modify the paginator class to make this work?
UPDATE:
i found out the problem:
in the core cake controller paginator merges default and options to create the find query.
but the options array is empty when using linkable to sort. because options is listed after default it overrides default and the empty array replaces the default array of options.
solution to this is extending the paginate function inside of app_controller.php and unsetting the options array order value if it is empty:
(line 1172 in cake/libs/controller/controller.php)
if(empty($options["order"])){
unset($options["order"]);
}
then the options will not be overwritten by thte blank array.
of course this should not be changed inside of controller.php, but put it in app_controller.php and move it to your app folder.
On CakePHP 3 this problem can be solved by adding 'sortWhitelist' params to $this->paginate on your controller.
$this->paginate = [
// ...
'sortWhitelist' => ['id', 'status', 'Attendance.Person.first_name']
];
And then in your view:
echo $this->Paginator->sort('Name', 'Attendance.Person.first_name');
This is noted in the docs:
This option is required when you want to sort on any associated data, or computed fields that may be part of your pagination query:
However that could be easily missed by tired eyes, so hope this helps someone out there!

Categories