Jump to content

Consecutive krsort()


k0z

Recommended Posts

If i have an array of data (the values don't matter, only the keys), such as:

$myArray[21]  = 0;
$myArray[22] = 0;
$myArray[23] = 0;
$myArray[25]  = 0;
$myArray[24] = 0;
$myArray[26] = 0;

 

Running a krsort() on this array turns it into:

$myArray[26]
$myArray[25]
..
..
$myArray[21]

 

The problem is, these keys represent days of the month. If I had an array of:

$myArray[29]
$myArray[28]
$myArray[30]
$myArray[2]
$myArray[1]

 

I'd actually want this to be turned into: (EDIT: SORRY, the below values should be reversed because this is KRSORT and not KSORT. THIS GOES FOR ALL OF THE FOLLOWING EXAMPLES)

$myArray[28]
$myArray[29]
$myArray[30]
$myArray[1]
$myArray[2]

 

To represent an actual month.  In addition, the data might not roll over the next month, so the data could be exactly what the first example was.

 

Obviously, different months have different lengths, so the data could potentially be:

$myArray[28]
$myArray[27]
$myArray[1]
$myArray[2]

 

And this would need to be turned into:

$myArray[27]
$myArray[28]
$myArray[1]
$myArray[2]

 

What would the easiest way to do this be?

 

Thanks.

Link to comment
Share on other sites

uksort($array, "strnatcmp") should do the trick.

 

Tried your code:

 

$myarray = array(1=>'test',30=>'test',2=>'test',3=>'test');
uksort($myarray, "strnatcmp");
var_dump($myarray);

 

This should have returned the keys in order: 30,1,2,3

But it returned them in 1,2,3,30

 

?

Link to comment
Share on other sites

That's odd. What version of PHP are you using? I'm on 5.2.12 and just created a new script with this:

 

<?php
$myarray = array(1=>'one',30=>'thirty',2=>'two',3=>'three');
uksort($myarray, "strnatcmpdesc");
var_dump($myarray);
?>

 

 

 

 

Which output this:

 

array(4) { [1]=> string(3) "one" [30]=> string(6) "thirty" [2]=> string(3) "two" [3]=> string(5) "three" }

Link to comment
Share on other sites

Nevermind, you're right. I forgot I had set display_errors = off earlier. It is throwing a warning level error for me. It works, but it still throws a warning. I'm too tired to look into it right now, but perhaps tomorrow, to satisfy my curiosity.

Link to comment
Share on other sites

With or without the warning, the returned data is still incorrect. It returns:

array(4) { [1]=>  string(3) "one" [30]=>  string(6) "thirty" [2]=>  string(3) "two" [3]=>  string(5) "three" }

 

when it should be 30, 1, 2, 3

Link to comment
Share on other sites

Your numerical indexes don't contain enough information for this to work. With the current data, there is simply no way for a computer to know that the 1,2 are from a greater month than the 28,29,and 30 and to order them correctly.

 

Dates consist of year, month, and day parts and each of those parts are significant if you are making greater-than/less-than comparisons and sorting date values. If you make your problem general purpose and carry all three parts, your problem will be solved (look back at the Y2K problem.)

Link to comment
Share on other sites

Your numerical indexes don't contain enough information for this to work. With the current data, there is simply no way for a computer to know that the 1,2 are from a greater month than the 28,29,and 30 and to order them correctly.

 

Dates consist of year, month, and day parts and each of those parts are significant if you are making greater-than/less-than comparisons and sorting date values. If you make your problem general purpose and carry all three parts, your problem will be solved (look back at the Y2K problem.)

That's not *quite* correct, actually. If you look at the data:

1,2,28,29,30

 

The amount of numbers between the end of a month to 1 (with respect to months) can be a maximum of 3 (because february starts @ the 28th). Furthermore, the jump from e.g. 2 to 20, for e.g., is much greater. If there is a deviation of a number LARGER than 3, then it is obvious it should go through a simple krsort();

 

I'm aware that a much simpler solution would be to maintain the month - but currently, it's not an option.

Link to comment
Share on other sites

Your scheme falls apart if I want to operate on, for example, the 3rd through the end of the current month and the 1st and 2nd of next month. The values would be indistinguishable.

 

Even with the gap notion, one simple sort won't work. You would need to split the data at the gap, sort each group, then put the data back together.

 

... but currently, it's not an option.

^^^ It's never too late to fix a design problem. The earlier you fix a problem, the more time you will end up saving over the time you will waste working around the design flaws.

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.