//упорядоченный входной массив
$arr = [0,2,3,5,6,7,9,13,15,16,17,20];
//сюда будем складывать ranges: ["0","2-3","5-7",...]
$ranges = [];
//а в этой переменной будем хранить текущий range: [from, to]
$currentRange = [$arr[0],$arr[0]];
//перебираем со второго элемента и до +последнего
for($i = 1; $i <= count($arr); $i++){
//на последней итерации, когда $i > count($arr), просто закроем последний range
if(!isset($arr[$i])) {
$ranges[] = $currentRange[0] !== $currentRange[1] ? implode('-', $currentRange) : $currentRange[0];
} else {
//если последний элемент текущего range равен "текущее значение - 1" - продляем range на текущий элемент
if ($currentRange[1] === intval($arr[$i]) - 1) {
$currentRange[1] = $arr[$i];
} else {
//закрываем текущий range (скидываем в ranges новую строку)
$ranges[] = $currentRange[0] !== $currentRange[1] ? implode('-', $currentRange) : $currentRange[0];
//открываем новый range с текущего места
$currentRange = [$arr[$i], $arr[$i]];
}
}
}
//склеиваем результирующий массив в строку через запятую
$resultStr = implode(',', $ranges);
但最初是通过一个循环,就在 php 中:)
结果
第一个选项:
第二个选项:
将包含一个这样的数组:
也就是说,从中可以看出,如果单元格0和单元格1中的元素相同,那么它是唯一的,如果不同,那么这是一个范围。您可以稍后像这样过滤它:
已经输出
示例取自https://codereview.stackexchange.com/questions/80080/aggregate-array-values-into-ranges
您还可以在那里看到更多示例。
可能有更好的解决方案,但结果证明是匆忙中的相当不错的代码。写的评论比代码多...