RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 550879
Accepted
ilyaplot
ilyaplot
Asked:2020-08-01 23:44:26 +0000 UTC2020-08-01 23:44:26 +0000 UTC 2020-08-01 23:44:26 +0000 UTC

如何从数组中提取数字范围?

  • 772

我已经痛苦了一个小时了,我无法从数组中选择范围。假设我们有一个数组[0,1,2,3,5,6,7,9,13,20]。我想得到一个字符串作为输出0-3,5-7,9,13,20。
我试图循环遍历数组并使用next破折号prev替换数字或添加逗号,但出现了一些垃圾。告诉我,这个任务可能有简单的算法或 Yii2 中的助手吗?

массивы
  • 3 3 个回答
  • 10 Views

3 个回答

  • Voted
  1. Best Answer
    Visman
    2020-08-02T00:22:30Z2020-08-02T00:22:30Z

    但最初是通过一个循环,就在 php 中:)

    function array_to_string($arr) {
        sort($arr, SORT_NUMERIC);
        $kk = count($arr);
        $result = '';
    
        for ($i = 0; $i <= $kk; $i++) {
            if (isset($arr[$i])) {
                if (!count($a)) {
                    $a[] = $arr[$i];
                    continue;
                }
                if ($arr[$i] == end($a) + 1) {
                    $a[] = $arr[$i];
                    continue;
                }
            }
            if (count($a) < 3) {
                $result .= implode(',', $a) . ',';
            } else {
                $result .= reset($a) . '-'. end($a) . ',';
            }
            if (isset($arr[$i])) {
                $a = [$arr[$i]];
            }
        }
    
        return trim($result, ',');
    }
    
    echo array_to_string([0,1,2,3,5,6,7,9,13,20]) . "<br>\n";
    echo array_to_string([0,1,3,5,6,7,8,9,10,11,12,13,20,21]) . "<br>\n";
    

    结果

    0-3,5-7,9,13,20
    0,1,3,5-13,20,21
    
    • 3
  2. Алексей Шиманский
    2020-08-02T00:15:46Z2020-08-02T00:15:46Z

    第一个选项:

    $myArray = [0,1,2,3,5,6,7,9,13,20];
    
    //last value is dropped so add something useless to be dropped
    array_push($myArray, null);
    $rangeArray = array();
    
    array_walk($myArray, function($val) use (&$rangeArray){
        static $oldVal, $rangeStart;
    
        if (is_null($rangeStart))
            goto init;
    
        if ($oldVal+1 == $val) {
            $oldVal = $val;
            return;
        }
    
        if ($oldVal == $rangeStart) {
            array_push($rangeArray, $rangeStart);
            goto init;
        }
    
        array_push($rangeArray, $rangeStart . '-' . $oldVal);
    
        init: {
            $rangeStart = $val;
            $oldVal = $val;
        }
    });
    
    echo '<pre>'.print_r($rangeArray, true).'</pre>';
    

    第二个选项:

    $numbers = [0,1,2,3,5,6,7,9,13,20];
    
    $ranges[] = array($numbers[0],$numbers[0]); // initial value
    
    foreach ($numbers as $number) {
      $range    = array_pop($ranges);
      $extend   = ($range[1] == $number-1);
      $ranges[] = array($range[0],$extend ? $number : $range[1]);
      if (!$extend) $ranges[] = array($number,$number);
    }
    
    echo '<pre>'.print_r($ranges,TRUE).'</pre>';
    

    将包含一个这样的数组:

    Array
    (
        [0] => Array
            (
                [0] => 0
                [1] => 0
            )
        [1] => Array
            (
                [0] => 0
                [1] => 3
            )
        [2] => Array
            (
                [0] => 5
                [1] => 7
            )
        [3] => Array
            (
                [0] => 9
                [1] => 9
            )
        [4] => Array
            (
                [0] => 13
                [1] => 13
            )
        [5] => Array
            (
                [0] => 20
                [1] => 20
            )
    )

    也就是说,从中可以看出,如果单元格0和单元格1中的元素相同,那么它是唯一的,如果不同,那么这是一个范围。您可以稍后像这样过滤它:

    foreach ($ranges as $range) {
      $output[] = ($range[0] == $range[1]) ? $range[0] : $range[0].'-'.$range[1];
    }
    
    echo '<pre>'.print_r($output,TRUE).'</pre>';
    

    已经输出

    Array
    (
        [0] => 0-3
        [1] => 5-7
        [2] => 9
        [3] => 13
        [4] => 20
    )
    

    示例取自https://codereview.stackexchange.com/questions/80080/aggregate-array-values-into-ranges

    您还可以在那里看到更多示例。

    • 1
  3. Иван Пшеницын
    2020-08-02T00:23:15Z2020-08-02T00:23:15Z

    可能有更好的解决方案,但结果证明是匆忙中的相当不错的代码。写的评论比代码多...

    //упорядоченный входной массив
    $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);
    
    • 1

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何停止编写糟糕的代码?

    • 3 个回答
  • Marko Smith

    onCreateView 方法重构

    • 1 个回答
  • Marko Smith

    通用还是非通用

    • 2 个回答
  • Marko Smith

    如何访问 jQuery 中的列

    • 1 个回答
  • Marko Smith

    *.tga 文件的组重命名(3620 个)

    • 1 个回答
  • Marko Smith

    内存分配列表C#

    • 1 个回答
  • Marko Smith

    常规赛适度贪婪

    • 1 个回答
  • Marko Smith

    如何制作自己的自动完成/自动更正?

    • 1 个回答
  • Marko Smith

    选择斐波那契数列

    • 2 个回答
  • Marko Smith

    所有 API 版本中的通用权限代码

    • 2 个回答
  • Martin Hope
    jfs *(星号)和 ** 双星号在 Python 中是什么意思? 2020-11-23 05:07:40 +0000 UTC
  • Martin Hope
    hwak 哪个孩子调用了父母的静态方法?还是不可能完成的任务? 2020-11-18 16:30:55 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    Arch ArrayList 与 LinkedList 的区别? 2020-09-20 02:42:49 +0000 UTC
  • Martin Hope
    iluxa1810 哪个更正确使用:if () 或 try-catch? 2020-08-23 18:56:13 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5