Jump to content

[SOLVED] sorting


hchsk

Recommended Posts

Hello,

 

 

I am trying to sort an array of integers by value (these are scores), and return an array with keys defined by their place in the original list (their team number), and element values equal to their sorted order (the team rank).

 

This I have accomplished with:

 

 
//OPEN AND FIX GLITCH
$filename = "scorestore.txt";
$score = file($filename);
for ($counter = 0; $counter < count($score); $counter +=1) {$score[$counter] = intval($score[$counter]);}
$scores=$score;

//APPEND TEAM NUMBER TO SCORE
for ($counter = 0; $counter < count($score); $counter +=1) {$hold = key($scores)+1; $scores[$counter] = $scores[$counter] . '.' . $hold; next($scores);}

//SORT
rsort($scores);

//REMOVE SCORE
for ($counter = 0; $counter < count($score); $counter +=1)  {if (strlen(floor($scores[$counter]))==1) {$scores[$counter] = substr_replace($scores[$counter], '', 0, 2);}
                                     else {$scores[$counter] = substr_replace($scores[$counter], '', 0, 3);}
                                    }

//SWITCH to FORMAT: $scores[team#] = place
$scores = array_flip($scores);

 

Here's my problem: I want to allow for teams (keys) with equal original values (scores) to have equal new values (ranking) equal to the lesser of the two. Basically, now that I have accomplished the first part, I want to go back, check for equal values, and for every group of equal elements, ignore the first, and subtract 1 from the value of the rest. I would loop this count($score) many times, to go through all possible equal values.

 

I would welcome any help or solution, including one that discards the successful code I have written in favor of a new, working, overall solution.

 

 

Thank you for your time and help.

Link to comment
Share on other sites

Can you provide an example of what is stored in $scores array? And provide an example of the final output. I don't need anything other than that, except if you can, clarify what you want with equal values. But it'll be best if you can put that in the example. Thanks!

Link to comment
Share on other sites

I definitely can, thanks again for helping, I've been working on this alone for days now, trying everything I can think of, creating dozens of different types of loops, and combining variations of rsort(), arsort(), usort(), uasort(), doubling and krsorting arrays, nothing has worked. Now I'm afraid I thought of a *possible* solution by changing a previous piece of flawed code, but I deleted the attempt and now cannot figure out how to recreate it.

 

the scorestore.txt will equal something like this:

 

3
3
0
4
10
1
5
9
10
10

 

And by final output I'm assuming you mean the output I would desire, which would be an array $score where $score[teamnumber] == place. So print_r($score); would be:

 

Array ( [9] => 1 [5] => 1 [10] => 1 [8] => 4 [7] => 5 [4] => 6 [2] => 7 [1] => 7 [6] => 9 [3] => 10 )

Link to comment
Share on other sites

[9] => 1 because team 9 is tied for first place, as is [10] => 1 and [5] => 1.

 

each of these teams has an equal number (10) points.

the same is true of [2] => 7 and [6] => 7, each of these teams has 3 points, and as such, is tied for 7th place.

 

the team number is derived from the placement in the .txt file.

Link to comment
Share on other sites

OH I get it. The team numbers are the line numbers. Should have said so. LOL!

 

<?php
$filename = "scorestore.txt";
$score = file($filename);
$score = arsort($score);

 

Okay now for the special sorting. Can you explain that part?

Link to comment
Share on other sites

haha, i was trying to think of how to phrase that, for some reason i couldnt figure it out, i knew it was on the tip of my tongue. . . now i feel silly.

 

I'm actually confused as to where you got that code from? It's not from anything I posted, I just double checked. I'll post again what I have just in case. It gets it to the point where $scores[team#] == rank, but it does not account for ties, but instead seems to randomly? choose an order for teams with the same number of points.

 

<?php

//OPEN, ASSIGN CONTENTS TO $VAR AND SWITCH VALUES TO INTEGERS
$filename = "scorestore.txt";
$score = file($filename);
for ($counter = 0; $counter < count($score); $counter +=1) {$score[$counter] = intval($score[$counter]);}
$scores=$score;



//APPEND TEAM NUMBER TO SCORE
for ($counter = 0; $counter < count($score); $counter +=1) {$hold = key($scores)+1; $scores[$counter] = $scores[$counter] . '.' . $hold; next($scores);}

//SORT
rsort($scores);


//REMOVE SCORE
for ($counter = 0; $counter < count($score); $counter +=1) 	{if (strlen(floor($scores[$counter]))==1) {$scores[$counter] = substr_replace($scores[$counter], '', 0, 2);}
								 else {$scores[$counter] = substr_replace($scores[$counter], '', 0, 3);}
								}


//SWITCH to FORMAT: $scores[team#] = place
$scores = array_flip($scores);

Link to comment
Share on other sites

Well, you want it sorted right? There is a little bug in my code.

 

<?php
$filename = "scorestore.txt";
$score = file($filename);
arsort($score);

 

There, that should do it. If you var_dump($score), you'll see that it does exactly what you want. It's much shorter too! Note that the team number will be the keys + 1 because arrays offset at 0.

 

Now, can you explain the last part?

Link to comment
Share on other sites

the problem with that solution is twofold, it sets (in our example):

 

Array ( [9] => 10 [8] => 10 [4] => 10 [7] => 9 [6] => 5 [3] => 4 [1] => 3 [0] => 3 [5] => 1 [2] => 0 ) 

 

firstly, the values are revered, [9, 8, 4] should => 1, not 10. secondly, and the larger problem, is that [7] is set to 10, when it should be (without fixing the first problem) => 4.

 

remember that this is to get the placement of teams, while [9, 8, 4] are tied for first place, that does not mean that [7] is in second place. It is actually in fourth place.

 

i feel that the best route will be something along the lines of the script i showed you, which puts the teams in proper order, with their team# as the key, and then to write some sort of double loop such as:

 

 

for ($counter2 = 0; $counter2 < count($score); $counter2 +=1) {
     for ($counter = 0; $counter < count($score); $counter +=1) {
          if ($score[$scores[$counter]] == $score[$scores[$counter+1]]) {
               $scores[counter+1]-=1;
}}}

 

but nothing i have written has worked.

Link to comment
Share on other sites

Basically, now that I have accomplished the first part, I want to go back, check for equal values, and for every group of equal elements, ignore the first, and subtract 1 from the value of the rest. I would loop this count($score) many times, to go through all possible equal values.

^ that

Link to comment
Share on other sites

try

<?php
$test = array(3,3,0,4,10,1,5,9,10,10);
arsort($test);
$score = 'x';
$coount = 0;
$out = array();
foreach ($test as $k => $v){
$coount++;
if($v != $score) {
	$place = $coount;
	$score = $v;
}
$out[$k+1] = $place;
}
print_r($out);
?>

Link to comment
Share on other sites

---------THIS IS IN RESPONSE TO KEN, I WILL TRY YOUR CODE MOMENTARILY SASA, THANK YOU

 

 

ok, so using the code i gave, you have the array

 

Array ( [9] => 1 [5] => 2 [10] => 3 [8] => 4 [7] => 5 [4] => 6 [2] => 7 [1] => 8 [6] => 9 [3] => 10 )

 

but [9][5][10] should all be => 1

and [2][1] should both => 7

 

so what i was trying to explain was my vague grasp of how that could be accomplished. my idea is to create a for loop, that will execute count($score) many times, and within it, to check the team score of the elements, in the order they are being shown, not in the order of their keys, and every time they are equal, to reduce the value of all of the equal elements except the first, by one.

 

this should give the result:

 

Array ( [9] => 1 [5] => 1 [10] => 2 [8] => 4 [7] => 5 [4] => 6 [2] => 7 [1] => 7 [6] => 9 [3] => 10 )

 

after one loop. if i then put that function into another loop to be executed count($score) many times, it will catch [10], and (if there are ties involving more than three elements, as in this example there are not), any other elements that had been reduced in value, but still not to the value they should be at. by the end of this loop, i would have the output i want.

Link to comment
Share on other sites

ahhh! it works perfectly! but. . . . not when i substitute my array for his, what could be going wrong??

 

using scorestore.txt that is EXACTLY as i posted above, and replacing sasa's defined array with:

 

$filename = "scorestore.txt";
$test = file($filename);
for ($counter = 0; $counter < count($score); $counter +=1) {$test[$counter] = intval($score[$counter]);}

 

i get:

 

Array ( [8] => 1 [7] => 2 [4] => 3 [1] => 4 [2] => 4 [9] => 6 [5] => 6 [10] => 8 [6] => 9 [3] => 10 ) 

 

 

 

oddly, if i print_r both arrays, (his and mine at the same time, without applying the function) just to check, they print identically!

 

what could possibly be my error?

Link to comment
Share on other sites

:D i had just tried an === test, and a gettype test, and come to the realization, but wasnt yet sure how to fix it.

 

 

you've been an incredible help, it now works perfectly. i'm in awe of your skill to craft that function that i've struggled with for days. thank you so much.

 

if you have nothing better to do, i'd ask that you take a look at http://www.phpfreaks.com/forums/index.php/topic,250510.0.html where i feel confident i'm making another small error that i cannot identify, but may be clear to you.

 

regardless, i cannot say how grateful i am.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.