asort asorts instead of sorts :)

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
corkman
Forum Newbie
Posts: 14
Joined: Thu Apr 09, 2009 3:40 am

asort asorts instead of sorts :)

Post by corkman »

Hi, please take a look at this code:

Code: Select all

<?php
header("Content-Type: text/plain");
$testarray=Array();
$testarray[0]="2009.1.28 08:29:31";
$testarray[1]="2009.1.28 08:29:31";
$testarray[2]="2009.1.28 08:29:31";
$testarray[3]="2009.1.28 08:29:32";
$testarray2=Array();
$testarray2[0]="0";
$testarray2[1]="1";
$testarray2[2]="2";
$testarray2[3]="3";
asort($testarray);
reset($testarray);
while (list ($key, $val) = each ($testarray)) {
    echo($val." key=$key ".$testarray2[$key]."\n");
}
?>
This is the output, the first three strings came out reverse sorted :crazy: but otherwise (for non equal strings) it works as expected:

Code: Select all

2009.1.28 08:29:31 key=2 2
2009.1.28 08:29:31 key=1 1
2009.1.28 08:29:31 key=0 0
2009.1.28 08:29:32 key=3 3
Function asort should sort array and maintain indexes. Why the hell is it reverse-sorting already sorted strings? If you change sorting function to sort, it works as expected:

Code: Select all

2009.1.28 08:29:31 key=0 0
2009.1.28 08:29:31 key=1 1
2009.1.28 08:29:31 key=2 2
2009.1.28 08:29:32 key=3 3
But I need to sort the array and maintain indexes. How should I do this? I have php version 5.2.8. Is that a normal behaviour, or a bug?

My problem:
I have a log file, which starts with date and time, the rest is text string, which should not be sorted. So I divide the log lines into two arrays and sort only the first array with maintainging index. But I found that asort cannot be used, when it reverse sorts already sorted.

Basically, I need to sort the lines up to N-th character (N can be different for each line) and rest of the string on line should be ignored (not compared in sorting).

Please answer:
1. is this some crazy behaviour of asort?
2. what do you suggest to solve my problem?

Thank you and nice day to all.
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: asort asorts instead of sorts :)

Post by requinix »

It's not a bug. You asked it to sort the array. It did. The array is sorted.
If the different strings are identical then the array keys shouldn't matter. If they do in your code then you're doing something wrong.
corkman
Forum Newbie
Posts: 14
Joined: Thu Apr 09, 2009 3:40 am

Re: asort asorts instead of sorts :)

Post by corkman »

Ok, array is sorted, but imagine this:

2009.1.28 07:00:00 Program test started
2009.1.28 07:00:00 ended program test

First array holds "2009.1.28 07:00:00", second array holds the rest of the string, i.e. "Program test started".

With use of asort it would look like:

2009.1.28 07:00:00 ended program test
2009.1.28 07:00:00 program test started

Makes parfect sense now :roll:

What if I want to sort the lines in a file, but only up the first a few characters, which hold the time and date? With asort, the array is sorted, but the result is for nothing :(

When it is correct, why the sort function does not behave the same way?
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: asort asorts instead of sorts :)

Post by requinix »

So which one is your question? How to sort using only the first few characters, or how to make it keep the original order of elements when possible?

For the former: try a combination of usort (since it's not looking like you'll need the keys) and your own function that uses strncmp.
For the latter: if you don't like the sorting algorithm then you have to use another. Which would probably mean writing it yourself. Which is not that great. Assuming the messages are fixed then use usort and write a function that sorts based on date, time (strtok is good for extracting them), or if those all match, the message. Not by a regular sort, that is, but by sorting "program test started" as coming before "ended program test".
corkman
Forum Newbie
Posts: 14
Joined: Thu Apr 09, 2009 3:40 am

Re: asort asorts instead of sorts :)

Post by corkman »

Thank you for help, usort and ctrncmp looks like a way to go, I will try it.

I also found the quote from usort, I hope this won't be a problem for my case:
"A new sort algorithm was introduced. The cmp_function doesn't keep the original order for elements comparing as equal."

The above probably applies to asort also, but there's nothing about undefined behaviour on equal strings in asort man. That's why I was wondering, if it's not a bug of asort.

Btw, just my humble opinion - when function claims it maintains the indexes, but it does not, then something is wrong, no matter if the result is sorted ;)
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: asort asorts instead of sorts :)

Post by requinix »

corkman wrote:Btw, just my humble opinion - when function claims it maintains the indexes, but it does not, then something is wrong, no matter if the result is sorted ;)
It does maintain indexes. That is, the key => value relationship.
It's the order of the keys that changes.
corkman
Forum Newbie
Posts: 14
Joined: Thu Apr 09, 2009 3:40 am

Re: asort asorts instead of sorts :)

Post by corkman »

Hehe, you are right. So, if asort really sorts, maintains the indexes, and works fine, then we can claim, that these two arrays are equal :mrgreen:

Array
(
[2] => 28.1.2009 08:29:31
[1] => 28.1.2009 08:29:31
[0] => 28.1.2009 08:29:31
[3] => 28.1.2009 08:29:32
)
Array
(
[0] => 28.1.2009 08:29:31
[1] => 28.1.2009 08:29:31
[2] => 28.1.2009 08:29:31
[3] => 28.1.2009 08:29:32
)

No offense, I don't want to start a flamewar or get :offtopic: My opinion is, that asort behaves strange. Perhaps it's only a matter of better lawyer :)

Btw, I found a quick solution to my problem, twice asort reverseses the order again to correct order :)

asort($testarray);
asort($testarray);

which produces the perfect result :crazy: : sorted array, maintained indexes and maintained order. I'd like to know, what the authors of asort smoke, if they meant it to work like this :mrgreen:
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: asort asorts instead of sorts :)

Post by requinix »

I'm not trying to start a flamewar either, but you're just not getting it. :o

asort is doing exactly what it describes: "sorts an array such that array indices maintain their correlation with the array elements they are associated with." That's talking about how a key is paired with its value. Nothing else.

The fact that there are many identical values may be confusing you. The values in the sorted once and the sorted twice array look the same, but if you think of them in terms of "value #0", "value #1", and "value #2" then the order is different. The actual values are the same, but the order in which they are presented is different.

Say you have four apples, each with a sticker with a number (1, 2, 3, or 4). Three identical red apples and one green apple. Now you give them to some guy ("sort") to arrange in order of color.
What he does is sort them so the red ones come first, but he also took off the stickers and reapplied them so that the first red apple is #1, second is #2, and third is #3. He completely forgot which sticker originally came on which apple.
Now say you don't like that. Say that the number on the apple also means something else: like which tree it came from. If the guy takes off the stickers then you lose that information. You need the stickers to stay on.

So instead you give the four apples to this other guy ("asort"). He sorts the apples into the exact same order that the first guy did, except he didn't resticker the apples according to their new order. When you get the apples back you see that apple #3 is first, #2 is second, and #1 is third.
As far as you should care, the apples are in the correct order: three red ones then the green one. The fact that the numbers on the stickers are out of order shouldn't matter - you were sorting by color, not number.
If the numbers are in reverse order, it's just a side effect of how the guy sorted the apples. If you handed him the green one first, or if you gave him a red, the green, then the other two reds, the order could easily be different. Maybe #2, green, #1, #3. Unless you ask the guy exactly how he sorts apples you can't know about which order the stickers will come back in.

If you want it so that the sticker numbers are arranged in order according to which order you handed the apples to the sorting guy then you need a third guy ("usort") instead. This guy wants more money, but he'll sort according to exactly how you describe it to him. If you want the red apples first, okay. If you want the apples sorted by sticker number, okay. If you want both of those at the same time (first by color, then by number), that'll work too.
corkman
Forum Newbie
Posts: 14
Joined: Thu Apr 09, 2009 3:40 am

Re: asort asorts instead of sorts :)

Post by corkman »

That's a perfect and nice example, thanks for explaining, but I knew all this. What I was trying to say, that the "undefined" order of same values should be stated in asort man.

From usort man:
Note: If two members compare as equal, their order in the sorted array is undefined.
There's not such a statement in asort man.

All what you told is right, logical and you are correct. I understand, why is that happening. But in every array, there's third, "invisible" sticker, we can call it order key, which marks the order of items. This invisible key seems to be mandatory, when we want array sorted with maintained stickers. The example with the more expensive guy is excellent, but the computer donesn't have to care, which tree the apples came from, when he knows the "invisible" order key, so there should be no need for the more expensive guy, who will perhaps stick additional stickers onto apples to differ them.

You obviously won the case, the asort guy is not guilty, he sorted the apples by color, leaving the sticker with index at place, and noone told him, that he shouldn't mess with the apple order, it's the farmer's fault, that he wanted to save some bucks for aditional "invisible" stickers :)

But if is the order so unimportant, why is there such a note in usort function?

Thank you for your time and entertaining discussion.
Post Reply