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; | |||||
| } | |||||