Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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 312637d
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 2 deletions.
9 changes: 7 additions & 2 deletions src/Utility/Hash.php
Expand Up @@ -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);
Expand Down
53 changes: 53 additions & 0 deletions tests/TestCase/Utility/HashTest.php
Expand Up @@ -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()
*
Expand Down

0 comments on commit 312637d

Please sign in to comment.