Bug #70937 [Nab]: natsort/natcasesort change key data type

From: Date: Thu, 19 Nov 2015 08:15:57 +0000
Subject: Bug #70937 [Nab]: natsort/natcasesort change key data type
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-197331@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=70937&edit=1

 ID:                 70937
 User updated by:    David dot Gausmann at measX dot com
 Reported by:        David dot Gausmann at measX dot com
 Summary:            natsort/natcasesort change key data type
 Status:             Not a bug
 Type:               Bug
 Package:            Arrays related
 PHP Version:        5.6.15
 Block user comment: N
 Private report:     N

 New Comment:

Hello again,

I've read the documentation before creating this bug report, but I still didn't get it
after I found out how it behaves. The documentation simply doesn't sound like "be aware
your numeric keys will turn into strings".

It says:
>> This function implements a sort algorithm that orders alphanumeric strings in the way a
>> human being would while maintaining key/value associations. This is described as a "natural
>> ordering". An example of the difference between this algorithm and the regular computer string
>> sorting algorithms (used in sort()) can be seen in the example below. <<

The information must be hidden in "while maintaining key/value associations", but it is
not clear which consequences this has.
An additional information like this would be fine:
>> The maintenance of the key/value associations is performed via conversion of the numeric
>> keys into strings. Unlike sort() elements will be accessed after sorting via their old index (e. g.
>> $array[0] will return the element with index 0 and not the first element). If you don't need
>> this behaviour, call array_values after sort or use usort with 'strnatcasecmp'. <<

The same goes for natcasesort. It would be very fine when you add something like that to the
documentation.

Kind Regards
David Gausmann


Previous Comments:
------------------------------------------------------------------------
[2015-11-19 02:57:51] laruence@php.net

Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to
report
a bug at http://bugs.php.net/how-to-report.php



------------------------------------------------------------------------
[2015-11-18 18:23:29] nhojohl at gmail dot com

This is because natsort and natcasesort maintain the key association (it does not re-key the array).

An array must have sequential keys in order for json_encode to encode it as a natural array,
otherwise it converts the array to an associative array (an object) and maintains the key value
association.

If you use array_values on the resulting array after sorting it; it'l resolve your issue
(relevant reference: http://php.net/manual/en/function.natcasesort.php#32610)

Example:

$array = array('b', 'a', 'c');
natsort($array);
$array = array_values($array);
echo "After natsort:<br>\r\n", json_encode($array), "<br>\r\n";

$array = array('b', 'a', 'c');
natcasesort($array);
$array = array_values($array);
echo "After natcasesort:<br>\r\n", json_encode($array), "<br>\r\n";

------------------------------------------------------------------------
[2015-11-18 13:57:16] David dot Gausmann at measX dot com

Description:
------------
I am using php to transfer arrays via JSON.
After using natsort/natcasesort for sorting the resulting data aren't JSON arrays anymore. This
happens because natsort/natcasesort are changing the datatype of the array keys from int to string
(but only when the data becomes sorted; otherwise the key data type won't change).

A workaround is it to use usort with strnatcmp/strnatcasecmp as second parameter.

Test script:
---------------
<?php
$array = array('b', 'a', 'c');

echo "After creation:<br>\r\n", json_encode($array), "<br>\r\n";

$array = array('b', 'a', 'c');
sort($array);
echo "After sort:<br>\r\n", json_encode($array), "<br>\r\n";

$array = array('b', 'a', 'c');
rsort($array);
echo "After rsort:<br>\r\n", json_encode($array), "<br>\r\n";

$array = array('b', 'a', 'c');
natsort($array);
echo "After natsort:<br>\r\n", json_encode($array), "<br>\r\n";

$array = array('b', 'a', 'c');
natcasesort($array);
echo "After natcasesort:<br>\r\n", json_encode($array), "<br>\r\n";

$array = array('b', 'a', 'c');
usort($array, 'strnatcmp');
echo "After usort(strnatcmp):<br>\r\n", json_encode($array),
"<br>\r\n";

?>

Expected result:
----------------
In all used sort functions the result should be an array like
["a","b","c"].

Actual result:
--------------
Instead natsort/natcasesort return
{"1":"a","0":"b","2":"c"} in JSON
syntax.
Only the other sort functions return an array like ["a","b","c"].


------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=70937&edit=1


Thread (4 messages)

« previous php.bugs (#197331) next »