Php 将带数字的数组转换为序列和单个数字

Php 将带数字的数组转换为序列和单个数字,php,arrays,Php,Arrays,我有一个数组: $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);

我有一个数组:

$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 ? ',' : '');
        }
    }
}

一种方法是首先将阵列拆分为多组:

$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));

告诉我们你尝试了什么,Stackoverflow不是免费的编码site@DimitrisFilippou公平地说,我想让人们以全新的视角看待问题,但我已经编辑了我的问题。