Rubyでどう書く?:連続した数列を範囲形式にまとめたい
をPHPで
簡略化のため入力は最初から配列としています。
<?php
$data = [1, 2, 3, 5, 6, 10, 15, 16, 20];
$ranges = array_reduce($data, function ($current, $element) {
if (count($current) == 0) {
$current[] = [$element];
return $current;
}
$currentLastRange = end($current);
$currentLastNumber = end($currentLastRange);
if (($currentLastNumber + 1) == $element) {
if (count($currentLastRange) > 1) {
array_pop($currentLastRange);
}
$currentLastRange[] = $element;
array_pop($current);
$current[] = $currentLastRange;
} else {
$current[] = [$element];
}
return $current;
}, []);
$result = array_reduce($ranges, function ($current, $range) {
if ($current != '') {
$current .= ',';
}
$current .= implode($range, '-');
return $current;
}, '');
echo $result;
RubyのEnumerable#injectというのはEnumerable#reduceのエイリアスなんですね(recudeの方がエイリアス?)。勉強になりました。