我有一个数组:
$array = [1, 2, 3, 4, 6, 7, 8, 10, 12, 14, 15, 16, 20, 21, 26, 27, 28];我想把它转换成字符串,用破折号分隔序列。因此,上面的数组将变成:1-4, 6-8, 10, 12, 14-16, 20, 21, 26-28
我试着循环一个错误,检查前面的数字+1是否等于当前的数字,以确定我是否在循环中。没有完全做到这一点,而且感觉效率很低。关于如何解决这个问题,有什么建议和/或想法吗?
此代码未完成,不能完全工作:
asort($zips);
$formatted = '';
$sequence = [];
$inSequenceLoop = false;
foreach ($zips as $key => $zip) {
// $prev = $key === 0 ? false : $zips[$key - 1];
$current = $zip;
$next = $key === count($zips) - 1 ? false : $zips[$key + 1];
if ($current + 1 === $next) {// || ($next === false && ($prev + 1) === $current)) {
$sequence[] = $current;
$inSequenceLoop = true;
} else {
if ($inSequenceLoop) {
// end of sequence
if (count($sequence) === 1) {
$formatted .= $sequence[0] . ($next ? ',' : '');
} else {
$formatted .= array_shift($sequence) . '-' . array_pop($sequence) . ($next ? ',' : '');
}
// create empty sequence
$inSequenceLoop = false;
$sequence = [];
} else {
// loner
$formatted .= $current . ($next ? ',' : '');
}
}
}发布于 2017-11-03 16:57:16
一种方法是首先将数组分成几组:
$pre = $key = 0; // initialize previous value and set key
foreach ($array as $number) {
if ($number > $pre + 1) $key++; // if number is not next in sequence, increment key
$sets[$key][] = $pre = $number; // append to current key and set previous to current
}然后映射一个格式化函数以返回范围字符串,并对格式化的范围内爆。
$result = implode(', ', array_map(function($set) {
// return either single element or dash separated first and last element
return count($set) == 1 ? reset($set) : reset($set) . '-' . end($set);
}, $sets));如果应该将两个元素的范围格式化为单独的元素,那么format函数也可以考虑到这一点。
$result = implode(', ', array_map(function($set) {
switch (count($set)) {
case 1: return reset($set);
case 2: return reset($set) . ', ' . $set[1];
default: return reset($set) . '-' . end($set);
}
}, $sets));https://stackoverflow.com/questions/47099859
复制相似问题