array_slice与连续序列php

时间:2016-07-08 15:50:21

标签: php arrays slice

美好的一天!

我有13 range (1,13)的数组结构; 它就像

array(1,2,3,4,5,6,7,8,9,10,11,12,13);

$slice=2;
$ignore = 3;

我想要像array(3,4,5,8,9,10,13);

这样的数组结构

我尝试使用array_slice函数,但我无法按顺序偏移值

array_slice($array,2,13,true); 有没有办法忽略下一个3值并将切片添加到下一秒,直到最后一个数组,任何本机函数或键都很棒。

谢谢, 维基

2 个答案:

答案 0 :(得分:2)

使用array_merge(),函数1可以连接两个数组切片。这将返回一个新数组。

http://php.net/manual/en/function.array-merge.php

<?php
      $slice = 2;
      $ignore = 3;
      $a = array(1,2,3,4,5,6,7,8,9,10,11,12,13);
      $a = array_merge(array_slice($a, $slice,$ignore),array_merge(array_slice($a, 2* $slice + $ignore,3),  array_slice($a, 3* $slice + 2*$ignore)));
      var_dump($a);
?>

我希望你明白了。 :)

答案 1 :(得分:0)

这是一个递归执行n长度数组的“非对称”切片的函数:

function slice_asym(array $head, $exclude, $include)
{
    $keep = array_slice($head, $exclude, $include);
    $tail = array_slice($head, $exclude + $include);

    return $tail ? array_merge($keep, slice_asym($tail, $exclude, $include)) 
                 : $keep;
}

递归需要基本情况,其中递归停止,所有范围展开并返回。在我们的例子中,我们希望在tail不再包含元素时停止。

array_slice()总是返回一个数组 - 如果没有要为其给定偏移量返回的元素,array_slice()将返回一个空数组。因此,对于每次递归,我们希望:

  1. 切出我们想要的元素$keep

  2. 创建一个$tail - 这是数组的一个子集,它排除了我们都想忽略的元素并保留在当前范围内($exclude + $include)。

    < / LI>
  3. 如果$tail不为空,则创建一个新的递归级别。否则停止递归并将所有当前$keep元素与下一级递归的结果合并。

  4. 在伪代码中,这看起来像:

    # step 1: first recursion
    head = [1,2,3,4,5,6,7,8,9,10,11,12,13]
    keep =     [3,4,5]
    tail =           [6,7,8,9,10,11,12,13] # tail not empty
    
    # step 2: second recursion
    head =           [6,7,8,9,10,11,12,13] 
    keep =               [8,9,10]
    tail =                      [11,12,13] # tail not empty
    
    # step 3: third recursion
    head =                      [11,12,13] 
    keep =                            [13]
    tail =                              [] # tail empty: base case met!
    
    # return and merge `keep` elements
    [3,4,5] + [8, 9, 10] + [13] -> [3,4,5,8,9,10,13]
    

    根据您的示例,以下调用:

    $range  = range(1, 13); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
    $sliced = slice_asym($range, 2, 3);
    
    print_r($sliced);
    

    收率:

    Array
    (
        [0] => 3
        [1] => 4
        [2] => 5
        [3] => 8
        [4] => 9
        [5] => 10
        [6] => 13
    )
    

    修改

    如果您使用的是PHP 5.5或更高版本,这也是generator的一个很好的用例。

    这些很有用,因为:

      

    生成器允许您编写使用foreach迭代一组数据的代码,而无需在内存中构建数组,这可能会导致超出内存限制,或者需要相当长的处理时间来生成。

    因此,您不必预先创建一系列顺序值:

      

    相反,您可以编写一个生成器函数,它与普通函数相同,除了不是返回一次,生成器可以生成所需数量的次数,以便提供要迭代的值。

    我们可以为您的用例实现一个生成器,如下所示:

    /**
     * 
     * @param  int $limit  
     * @param  int $exclude
     * @param  int $include
     * @return int
     */
    function xrange_asym($limit, $exclude, $include) {
    
        if ($limit < 0 || $exclude < 0 || $include < 0) {
            throw new UnexpectedValueException(
                '`xrange_asym` does not accept negative values');
        }
    
        $seq = 1;
        $min = $exclude;
        $max = $exclude + $include;
    
        while ($seq <= $limit) {
    
            if ($seq > $min && $seq <= $max) {
                yield $seq;
            }
    
            if ($seq === $max) {
                $min = $exclude + $max;
                $max = $exclude + $include + $max;
            }
    
            $seq = $seq + 1;
        }
    }
    

    并使用它,如下:

    foreach (xrange_asym(13, 2, 3) as $number) {
        echo $number . ', '; //  3, 4, 5, 8, 9, 10, 13
    }
    

    或使用iterator_to_array()生成整个范围作为数组:

    print_r(iterator_to_array(xrange_asym(13, 2, 3)));
    

    希望这会有所帮助:)