1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-11-21 22:32:41 +01:00

Introduce "phutil_partition()" and natural case sorting for "msortv(...)"

Summary:
Ref T13546. Pull some small utility changes out of the deeper stack of "land/markers" changes.

"phutil_partition()" makes it easier to write code that loops over a list grouping elements, then acts on each group. This kind of code is not terribly common, but often feels awkward when implemented with raw primitives.

"msortv()" can support "natural" sorting, which sorts "feature1", "feature2", ..., "feature10" in a more human-readable order.

Test Plan: Ran unit tests, used new behaviors elsewhere in "arc markers" workflows.

Maniphest Tasks: T13546

Differential Revision: https://secure.phabricator.com/D21371
This commit is contained in:
epriestley 2020-06-30 06:35:27 -07:00
parent 33484b43c9
commit c53c05e5b2
3 changed files with 75 additions and 1 deletions

View file

@ -925,6 +925,8 @@ phutil_register_library_map(array(
'mpull' => 'utils/utils.php', 'mpull' => 'utils/utils.php',
'msort' => 'utils/utils.php', 'msort' => 'utils/utils.php',
'msortv' => 'utils/utils.php', 'msortv' => 'utils/utils.php',
'msortv_internal' => 'utils/utils.php',
'msortv_natural' => 'utils/utils.php',
'newv' => 'utils/utils.php', 'newv' => 'utils/utils.php',
'nonempty' => 'utils/utils.php', 'nonempty' => 'utils/utils.php',
'phlog' => 'error/phlog.php', 'phlog' => 'error/phlog.php',
@ -979,6 +981,7 @@ phutil_register_library_map(array(
'phutil_loggable_string' => 'utils/utils.php', 'phutil_loggable_string' => 'utils/utils.php',
'phutil_microseconds_since' => 'utils/utils.php', 'phutil_microseconds_since' => 'utils/utils.php',
'phutil_parse_bytes' => 'utils/viewutils.php', 'phutil_parse_bytes' => 'utils/viewutils.php',
'phutil_partition' => 'utils/utils.php',
'phutil_passthru' => 'future/exec/execx.php', 'phutil_passthru' => 'future/exec/execx.php',
'phutil_person' => 'internationalization/pht.php', 'phutil_person' => 'internationalization/pht.php',
'phutil_register_library' => 'init/lib/core.php', 'phutil_register_library' => 'init/lib/core.php',

View file

@ -966,4 +966,38 @@ final class PhutilUtilsTestCase extends PhutilTestCase {
} }
} }
public function testArrayPartition() {
$map = array(
'empty' => array(
array(),
array(),
),
'unique' => array(
array('a' => 'a', 'b' => 'b', 'c' => 'c'),
array(array('a' => 'a'), array('b' => 'b'), array('c' => 'c')),
),
'xy' => array(
array('a' => 'x', 'b' => 'x', 'c' => 'y', 'd' => 'y'),
array(
array('a' => 'x', 'b' => 'x'),
array('c' => 'y', 'd' => 'y'),
),
),
'multi' => array(
array('a' => true, 'b' => true, 'c' => false, 'd' => true),
array(
array('a' => true, 'b' => true),
array('c' => false),
array('d' => true),
),
),
);
foreach ($map as $name => $item) {
list($input, $expect) = $item;
$actual = phutil_partition($input);
$this->assertEqual($expect, $actual, pht('Partition of "%s"', $name));
}
}
} }

View file

@ -433,6 +433,14 @@ function msort(array $list, $method) {
* @return list Objects ordered by the vectors. * @return list Objects ordered by the vectors.
*/ */
function msortv(array $list, $method) { function msortv(array $list, $method) {
return msortv_internal($list, $method, SORT_STRING);
}
function msortv_natural(array $list, $method) {
return msortv_internal($list, $method, SORT_NATURAL | SORT_FLAG_CASE);
}
function msortv_internal(array $list, $method, $flags) {
$surrogate = mpull($list, $method); $surrogate = mpull($list, $method);
$index = 0; $index = 0;
@ -455,7 +463,7 @@ function msortv(array $list, $method) {
$surrogate[$key] = (string)$value; $surrogate[$key] = (string)$value;
} }
asort($surrogate, SORT_STRING); asort($surrogate, $flags);
$result = array(); $result = array();
foreach ($surrogate as $key => $value) { foreach ($surrogate as $key => $value) {
@ -1966,3 +1974,32 @@ function phutil_glue(array $list, $glue) {
return array_select_keys($tmp, $keys); return array_select_keys($tmp, $keys);
} }
function phutil_partition(array $map) {
$partitions = array();
$partition = array();
$is_first = true;
$partition_value = null;
foreach ($map as $key => $value) {
if (!$is_first) {
if ($partition_value === $value) {
$partition[$key] = $value;
continue;
}
$partitions[] = $partition;
}
$is_first = false;
$partition = array($key => $value);
$partition_value = $value;
}
if ($partition) {
$partitions[] = $partition;
}
return $partitions;
}