Sorting Multidimensional Array by Specific Key - php

EDIT: For anyone who might come across this post with a similar problem, It was solved by taking konforce's supplied answer and tweaking around a bit with the custom sorting function:
function cmp($a, $b) {
if ($a[5] == $b[5]) {
return ($a[3] < $b[3]) ? -1 :1;
}
return ($a[5] > $b[5]) ? -1 : 1;
}
Notice $a[5] == $b[5] does not return zero. It was changed to check who has the most losses and then sort it in ASC order. I'm sure you can even keep going and add another if-statement in there in-case they have the same losses.
Lastly, all you do is usort($ARRAY, "cmp"); and finito!!!
Original Post
My apologies for coming up with yet another MD Array sorting question but I'm just not getting it. I've searched aplenty
for a solution and although many sites have provided what seemed like a logical answer I still have not been able to figure it out.
My problem is since I'm still learning its been rather difficult for me to grasp the concept of using usort with a custom comparing
function. Atleast, thats what I have seen the most when others have tried to sort MD Arrays.
I'm working on a small project to sharpen up on my php skills. Its a very basic tournament standings script that holds a team's information within an array. I would like to sort the array by most points($array[X][X][5]).
So the array looks something like this:
Array (
[0] => Array (
[0] => Array (
[0] => cooller
[1] => 6
[2] => 6
[3] => 0
[4] => 0
[5] => 18
)
)
[1] => Array (
[0] => Array (
[0] => strenx
[1] => 9
[2] => 5
[3] => 1
[4] => 3
[5] => 18
)
)
[2] => Array (
[0] => Array (
[0] => rapha
[1] => 10
[2] => 8
[3] => 1
[4] => 1
[5] => 25
)
) [3] => Array (
[0] => Array (
[0] => ronald reagan
[1] => 5
[2] => 4
[3] => 0
[4] => 1
[5] => 13
)
)
)
I would like to sort it by most points(cell #5), so it would look like this after sorting:
Array (
[0] => Array (
[0] => Array (
[0] => rapha
[1] => 10
[2] => 8
[3] => 1
[4] => 1
[5] => 25
)
)
[1] => Array (
[0] => Array (
[0] => cooller
[1] => 6
[2] => 6
[3] => 0
[4] => 0
[5] => 18
)
)
[2] => Array (
[0] => Array (
[0] => strenx
[1] => 9
[2] => 5
[3] => 1
[4] => 3
[5] => 18
)
)
[3] => Array (
[0] => Array (
[0] => ronald reagan
[1] => 5
[2] => 4
[3] => 0
[4] => 1
[5] => 13
)
)
)
The player with 25 points would be at the top, followed by 18, 18, and lastly 13. Sorry for my earlier post, was having difficulty wording my question correctly. Thanks in advanced!

I think you want something like this:
usort($standings, function($a, $b) { return $b[0][5] - $a[0][5]; });
Or prior to PHP 5.3:
function cmp($a, $b) { return $b[0][5] - $a[0][5]; }
usort($standings, 'cmp');
When using usort, the $a and $b parameters will be one "layer" into the supplied array. So in your case, an example of $a or $b will be:
[0] => Array (
[0] => cooller
[1] => 6
[2] => 6
[3] => 0
[4] => 0
[5] => 18
)
I'm not sure why you have an extra containing array there, but as you can see, you want to sort based on the [0][5] position.

usort($standings[0][0][5], 'cmp') won't work because the first parameter isn't an array to sort, it's just a single number, the points.

Related

Merge 2 arrays when keys of 1 matches value in 2

I need help figuring out what I am doing wrong and/or if there is a better way to do it, my question is two part. The first part is I am using Joomla 3.5.1 and in the template I have two fieldsets, one that allows the user to enter links to their social media accounts and the second I am attempting to make a sort if you will using a set of drop downs. This may or may not be the best so I am open to options here.
Now for the second part. I am able to bring in the both field sets into separate arrays, for simplicity array 1 and array 2. Array 1 has the links and array 2 has the order. So my question is this, how would be the best way to loop through and match everything up while removing the empties in array 1 and "none" in array 2.
One thought I did have is should array 2 not be multidimensional and let the key be the "soXYZ", but then how would the best way to match it up knowing that the lengths are different and the order as well.
Array 2 where (-1) are "None" in the drop downs
Array
(
[0] => soPhone
[1] => soContact
[2] => soFacebook
[3] => soMap
[4] => -1
[5] => -1
[6] => -1
[7] => -1
[8] => -1
[9] => -1
[10] => -1
[11] => -1
[12] => -1
[13] => -1
[14] => -1
)
Array 1
Array
(
[0] => Array
(
[0] => soPhone
[1] => 555.867.5309
)
[1] => Array
(
[0] => soContact
[1] => Contact
)
[2] => Array
(
[0] => soMap
[1] => Map
)
[3] => Array
(
[0] => soFacebook
[1] => Facebook
)
[4] => Array
(
[0] => soTwitter
[1] => Twitter
)
[5] => Array
(
[0] => soGoogle
[1] => Google Plus
)
[6] => Array
(
[0] => soLinkedIn
[1] => Linked In
)
[7] => Array
(
[0] => soPinterest
[1] => Pinerest
)
[8] => Array
(
[0] => soYouTube
[1] => YouTube
)
[9] => Array
(
[0] => soVimeo
[1] => Vimeo
)
[10] => Array
(
[0] => soYelp
[1] => Yelp
)
[11] => Array
(
[0] => soInstagram
[1] => Instagram
)
[12] => Array
(
[0] => soTripAdvisor
[1] => Trip Advisor
)
[13] => Array
(
[0] => soHouzz
[1] => Houzz
)
[14] => Array
(
[0] => soAngiesList
[1] => Angies List
)
)
Array Result
Array
(
[0] => Array
(
[0] => soPhone
[1] => 555.867.5309
)
[1] => Array
(
[0] => soContact
[1] => Contact
)
[2] => Array
(
[0] => soFacebook
[1] => Facebook
)
[3] => Array
(
[0] => soMap
[1] => Map
)
)
Any guidance is appreciated.
After the power of posting I was able to eventually get my desired result, which as follows:
I set up three arrays arrLinks (originally Array 1) , arrLinksOrder (originally Array 2) and arrLinksCombined (Array Result), then populated arrLinks with the user entered text links on the template, arrLinksOrder pulls from the drop downs.
My original plan was to have arrLinks be multidimensional but in the end I just set the key's for each in my code.
I then used this stackoverflow link to help combine the arrLinksOrder and arrLinks. Once everything is combined I was able to build the html and really clean up the file to something easier to manage.
Code below:
// Populate the contents of the text-box into an array
$arrLinks = array(
"soFacebook"=> $tbFacebook,
"soTwitter"=> $tbTwitter,
"soGoogle"=> $tbGoogle,
"soLinkedIn"=> $tbLinkedIn,
"soPinterest"=> $tbPinterest,
"soYouTube"=> $tbYouTube,
"soInstagram"=> $tbInstagram,
);
// Populate an array (arrLinksOrder) with the drop down selections
for ($i=1; $i < ($linksCount+1); $i++) {
$varName = 'listSocialOrder'.$i;
$arrLinksOrder[$i] = $$varName;
}
// Combine arrLinksOrder and arrLinks, if the arrLinksOrder exists in arrLinks
foreach($arrLinksOrder as $key) {
if(array_key_exists($key, $arrLinks)) {
$arrLinksCombined[$key] = $arrLinks[$key];
}
}
If anyone has any improvements please feel free to share, this is what worked for me at the time.

How to merge these two arrays in this specific order

I have two array as following
Array
(
[0] => 641
[1] => 622
[2] => 100
[3] => 6431
)
Array
(
[0] => 64.1
[1] => 62.2
[2] => 10
[3] => 643.1
)
How can I make it as following
Array
(
[0] => 641
[1] => 64.1
[2] => 622
[3] => 62.2
[4] => 100
[5] => 10
[6] => 6431
[7] => 643.1
)
It's as simple as
$result=array_merge($array1,$array2);
Note: Your values wont be in the order you presented though. If that is important then you need to loop through your arrays to build a new array accordingly.
Ummm ok here is that version as well
if(count($array1)==count($array2))
{
for($i=0;$i<count($array1);$i++)
{
$result[]=$array1[$i];
$result[]=$array2[$i];
}
}
print_r($result);
Fiddle
Manual
you can use array_merge() function merges one or more arrays into one array.
example:
array_merge(array1,array2,array3...)

PHP Count number of Arrays

Simple question that I am struggling to find answer for. I have an array as follows:
Array (
[0] => Array ( [0] => 2014-05-14 02:11:16 [1] => 1 )
[1] => Array ( [0] => 2014-05-19 05:05:17 [1] => 76 )
[2] => Array ( [0] => 2014-05-20 00:28:41 [1] => 35 )
[3] => Array ( [0] => 2014-05-21 01:24:01 [1] => 25 )
)
All I need to do is count how many Arrays there are.
The answer based on the above would be 4 (0,1,2&3).
I am positive this is a very simple thing but I cannot fathom how - any and all suggestions welcomed.
Using count() should work for you :
$num = count($array);

Yii createCommand() return data set in different array format

I'm a beginner in this framework. Though I have gone over the basics, there is one thing which is troubling me. As of now, I'm using
$group_sql = "SELECT uid FROM {$table}";
$group_users = Yii::app()->db->createCommand($group_sql)->queryAll();
print_r($group_users);
results in
Array
(
[0] => Array
(
[uid] => 2
)
[1] => Array
(
[uid] => 3
)
[2] => Array
(
[uid] => 4
)
[3] => Array
(
[uid] => 5
)
)
But I'd like to change the format in which the data is returned. What I'm looking for is something like
Array
(
[0] => 2
[1] => 3
[2] => 4
[3] => 5
)
OR
Array
(
[uid] => Array
(
[0] => 2
[1] => 3
[2] => 4
[3] => 5
)
)
I'm aware that I can go through the documentation and get my answer, but due to time constraints, I'm taking the liberty to shamelessly ask this over here.
Thanks in advance.
Use queryColumn() method instead of queryAll()

Working with multi-level arrays

hello i am learning PHP and came upon this multi-level array after using print_r on $this->root
Array (
[0] => 9
[obj] => 3562
[gen] => 0
[1] => Array (
[0] => 5
[1] => Array (
[/AcroForm] => Array (
[0] => 8
[1] => 3563
[2] => 0
)
[/Metadata] => Array (
[0] => 8
[1] => 3559
[2] => 0
)
[/PageLabels] => Array (
[0] => 8
[1] => 3389
[2] => 0
)
[/Pages] => Array (
[0] => 8
[1] => 3392
[2] => 0
)
[/Type] => Array (
[0] => 2
[1] => /Catalog
)
)
)
) Array (
[0] => 9
[obj] => 8
[gen] => 0
[1] => Array (
[0] => 5
[1] => Array (
[/Type] => Array (
[0] => 2
[1] => /Catalog
)
[/Pages] => Array (
[0] => 8
[1] => 1
[2] => 0
)
[/OpenAction] => Array (
[0] => 6
[1] => Array (
[0] => Array (
[0] => 8
[1] => 3
[2] => 0
)
[1] => Array (
[0] => 2
[1] => /FitH
)
[2] => Array (
[0] => 0
)
)
)
[/PageLayout] => Array (
[0] => 2
[1] => /OneColumn
)
)
)
)
i have an question about the behavior of using multi-level arrays, i want to use this function
$pages = $this->pdf_resolve_object($this->c, $this->root[1][1]['/Pages']);
and $this->root[1][1]['/Pages'] which i believe is used to check the array for these keys and if it exists then use as variable for pdf_resolve_object
so my question is 2-fold, one is does $this->root[1][1]['/Pages'] check the array and goes through the keys? if not what is its behavior? and 2 when it checks the array does it go through just the top 4 keys or all of the sub-keys?
If someone can help or link me to some learning material that would be much appreciated, thank you!
1) It does not check for the presence of the array keys -- rather it assumes that those keys already exist and passes the value into the function. If any of the keys did not exist, PHP would issue an E_NOTICE to the effect of Notice: Undefined index: that the key was not found. To check for them would require a call to isset() or array_key_exists() like:
if (isset($this->root[1][1]['/Pages'])) {
$pages = $this->pdf_resolve_object($this->c, $this->root[1][1]['/Pages']);
}
2) There is no need for it to iterate through to find the keys. Knowing the array keys already means they can be accessed directly without iteration. In memory, PHP has stored the array keys and the memory locations of the values they point to. Therefore, with the key alone, PHP can return the value without needing to traverse the array.
There is a lot of good information in the PHP manaul on Arrays

Categories