Skip to content
Permalink
Browse files

Correctly sort sparse data that uses numeric keys.

When numeric keyed results are sorted, and the sort key is sparse we
should attempt to sort the data as best we can.

Refs #8177
  • Loading branch information...
markstory committed Feb 11, 2016
1 parent 6b3aaa2 commit 312637db794fab67c8f7e9a7c5df0b519c268944
Showing with 60 additions and 2 deletions.
  1. +7 −2 src/Utility/Hash.php
  2. +53 −0 tests/TestCase/Utility/HashTest.php
@@ -933,12 +933,17 @@ public static function sort(array $data, $path, $dir = 'asc', $type = 'regular')
$data = array_values($data);
}
$sortValues = static::extract($data, $path);
$sortCount = count($sortValues);
$dataCount = count($data);
// Make sortValues match the data length, as some keys could be missing
// the sorted value path.
if ($sortCount < $dataCount) {
$missingData = count($sortValues) < $dataCount;
if ($missingData && $numeric) {
foreach ($data as $key => $value) {
// Get the value without the leading '{n}'.
$sortValues[$key] = static::get($value, substr($path, 4));
}
} elseif ($missingData) {
$sortValues = array_pad($sortValues, $dataCount, null);
}
$result = static::_squash($sortValues);
@@ -1774,6 +1774,59 @@ public function testSortRegularIgnoreCase()
$this->assertEquals($expected, $sorted);
}
/**
* Test sorting on a nested key that is sometimes undefined.
*
* @return void
*/
public function testSortSparse()
{
$data = [
[
'id' => 1,
'title' => 'element 1',
'extra' => 1,
],
[
'id' => 2,
'title' => 'element 2',
'extra' => 2,
],
[
'id' => 3,
'title' => 'element 3',
],
[
'id' => 4,
'title' => 'element 4',
'extra' => 4,
]
];
$result = Hash::sort($data, '{n}.extra', 'desc', 'natural');
$expected = [
[
'id' => 4,
'title' => 'element 4',
'extra' => 4,
],
[
'id' => 2,
'title' => 'element 2',
'extra' => 2,
],
[
'id' => 1,
'title' => 'element 1',
'extra' => 1,
],
[
'id' => 3,
'title' => 'element 3',
],
];
$this->assertSame($expected, $result);
}
/**
* Test insert()
*

0 comments on commit 312637d

Please sign in to comment.
You can’t perform that action at this time.