Changeset View
Changeset View
Standalone View
Standalone View
src/utils/utils.php
Show First 20 Lines • Show All 427 Lines • ▼ Show 20 Lines | |||||
* This sort is stable, well-behaved, and more efficient than `usort()`. | * This sort is stable, well-behaved, and more efficient than `usort()`. | ||||
* | * | ||||
* @param list List of objects to sort. | * @param list List of objects to sort. | ||||
* @param string Name of a method to call on each object. The method must | * @param string Name of a method to call on each object. The method must | ||||
* return a @{class:PhutilSortVector}. | * return a @{class:PhutilSortVector}. | ||||
* @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; | ||||
foreach ($surrogate as $key => $value) { | foreach ($surrogate as $key => $value) { | ||||
if (!($value instanceof PhutilSortVector)) { | if (!($value instanceof PhutilSortVector)) { | ||||
throw new Exception( | throw new Exception( | ||||
pht( | pht( | ||||
'Objects passed to "%s" must return sort vectors (objects of '. | 'Objects passed to "%s" must return sort vectors (objects of '. | ||||
'class "%s") from the specified method ("%s"). One object (with '. | 'class "%s") from the specified method ("%s"). One object (with '. | ||||
'key "%s") did not.', | 'key "%s") did not.', | ||||
'msortv()', | 'msortv()', | ||||
'PhutilSortVector', | 'PhutilSortVector', | ||||
$method, | $method, | ||||
$key)); | $key)); | ||||
} | } | ||||
// Add the original index to keep the sort stable. | // Add the original index to keep the sort stable. | ||||
$value->addInt($index++); | $value->addInt($index++); | ||||
$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) { | ||||
$result[$key] = $list[$key]; | $result[$key] = $list[$key]; | ||||
} | } | ||||
return $result; | return $result; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,494 Lines • ▼ Show 20 Lines | foreach ($list as $key => $ignored) { | ||||
if ($key !== $last_key) { | if ($key !== $last_key) { | ||||
$tmp[] = $glue; | $tmp[] = $glue; | ||||
$keys[] = last_key($tmp); | $keys[] = last_key($tmp); | ||||
} | } | ||||
} | } | ||||
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; | |||||
} |