【问题标题】:How to start looping through an array at a different index and finishing the entire array如何开始循环遍历不同索引处的数组并完成整个数组
【发布时间】:2019-08-05 16:38:24
【问题描述】:

我试图弄清楚如何开始循环遍历不同索引的数组,但是当它到达末尾时,它会循环回到开头并完成数组。基本上,我需要能够动态改变数组的偏移量。

我正在尝试做的是将字母表中的一个字母与另一个字母表字母关联起来,以将字符串混合在一起。

假设我有一个这样的随机数组

$arr = array('a' => 'g', 'b' => 'w', 'c' => 'j', 'd' => 'y', 'e' => 'k');

然后我有一个这样的字符串

$string = 'abcde';

假设我需要从数组中的索引2 开始,这将是'c' => 'j',然后将数组完成到末尾,然后循环回到开头直到完成。

我想要做的是用数组中与之关联的相应字母替换每个字母。所以替换后的最终字符串看起来像

我会用

重构数组
$build = strtr($string,$arr);

会回显gwjyk

但我需要从数组中的一个随机点开始,然后完成它,然后回到开始并完成整个数组。

所以也许我的偏移量是2

$offset = 2;

【问题讨论】:

  • 我想有更好的方法来做任何你想做的事情。如果你告诉我们完整的故事,有人可以提出建议
  • 你在混淆...55 => 6的索引而不是2
  • @RiggsFolly 你是对的我编辑了我的问题以匹配我的确切情况。
  • strstr 有什么问题?你需要什么自定义循环?
  • 我会先执行array_slice 然后array_merge 以正确的顺序创建数组并从头开始索引,然后从头到尾遍历一次。

标签: php arrays


【解决方案1】:

正如我在 cmets 中提到的,我会使用 array_slice 来处理这个问题,然后合并两个数组以便简单地获得一个新数组,然后从头到尾循环遍历它。

这是一个功能齐全的解决方案(和一个runnable version)- 尽管我想指出偏移量实际上根本不会改变结果:

/**
 * Goes through a string and replaces letters based on an array "map".
 * 
 * @param string - $string
 * @param int - $offset
 * 
 * @return string
 */
function change_letters( $string, $offset ) {
    $letters = ['a' => 'g', 'b' => 'w', 'c' => 'j', 'd' => 'y', 'e' => 'k'];
    // some defensive code to prevent notices or errors
    if ( (int)$offset > count($letters)) {
        echo '<p>Error: Offset is larger than the array of letters!</p>';
        return $string;
    }
    // build new array based on passed-in offset
    $new_array = array_slice($letters, $offset) + array_slice($letters, 0, $offset);
    // at this point, array is ['c' => 'j', 'd' => 'y', 'e' => 'k', 'a' => 'g', 'b' => 'w']
    // loop through the letters to replace...
    foreach($new_array AS $from => $to) {
        // swaps all instances of the "from" letter to the "to" letter in the string.
        // NOTE: this could be easily modified to only replace n instances of the "from" letter
        // like so: $string = str_ireplace( $from, $to, $string, 1); - would only replace 1 instance
        $string = str_ireplace( $from, $to, $string );
    }

    return $string;
}

// Sample usage:
$word = 'abcde';
$new_word = change_letters( $word, 2); // "gwjk"
var_dump(2, $new_word);
$new_word = change_letters( $word, 5); // "gwjk"
var_dump(5, $new_word);
$new_word = change_letters( $word, 6); // "abcde"
var_dump(5, $new_word);

【讨论】:

    【解决方案2】:

    你可以试试:

    <?php
    
    $arr = array(1 => 2, 3 => 4, 5 => 6, 7 => 8, 9 => 0);
    $STARTING_KEY = 3;
    
    $array_keys = array_keys($arr);
    $starting_index = array_search($STARTING_KEY, $array_keys);
    
    for ($i = $starting_index; $i < sizeof($arr); $i++) {
        echo $arr[$array_keys[$i]] . "\n";
    }
    for ($i = 0; $i < $starting_index; $i++) {
        echo $arr[$array_keys[$i]] . "\n";
    }
    

    【讨论】:

      【解决方案3】:

      这将测试字符串的所有可能偏移量

      $arr = array('a' => 'g', 'b' => 'w', 'c' => 'j', 'd' => 'y', 'e' => 'k');
      $str = "abcde";
      $strlen = strlen($str);
      $keys = array_keys($arr);
      
      for ($j = 0; $j < $strlen; $j++) 
      {
          $startIndex = $j;
          echo "offset: " . $startIndex . ": ";
      
          for ($i = $startIndex; $i < $strlen; $i++ ) 
          {
              $char = substr( $str, $i, 1 );
              echo $arr[$char];
          }
          for ($i = 0; $i < $startIndex; $i++ ) 
          {
              $char = substr( $str, $i, 1 );
              echo $arr[$char];
          }
          echo "\n";
      }
      

      输出:

      offset: 0: gwjyk
      offset: 1: wjykg
      offset: 2: jykgw
      offset: 3: ykgwj
      offset: 4: kgwjy
      

      【讨论】:

      • @dWinder OP 澄清了他想要什么并相应地改变了答案。
      【解决方案4】:

      如评论中所述,您的示例数据的另一个选项可能是使用 array_slice 并设置偏移量和长度参数并使用 array_merge:

      $arr = array('a' => 'g', 'b' => 'w', 'c' => 'j', 'd' => 'y', 'e' => 'k');
      
      $top = array_slice($arr, 0, 2);
      $rest = array_slice($arr, 2);
      
      print_r(array_merge($rest, $top));
      
      Array
      (
          [c] => j
          [d] => y
          [e] => k
          [a] => g
          [b] => w
      )
      

      【讨论】:

        【解决方案5】:

        所有的数组切片或使用两个循环从 x 循环到第一个结束,然后开始到 x 秒,都很好……但恕我直言,它们并没有成为最易读的代码。

        这样的“偏移循环”可以通过数字索引数组以非常简单的方式实现 - 一个简单的for循环,并通过使用模数“钳制”索引数组元素的总数。

        所以在这种情况下,我可能更喜欢以下方法:

        $arr = array('a' => 'g', 'b' => 'w', 'c' => 'j', 'd' => 'y', 'e' => 'k');
        
        $c = count($arr);
        $search = array_keys($arr);
        $replace = array_values($arr);
        
        $offset = 2; // zero-based
        
        for( $i = 0; $i < $c; ++$i ) {
          $idx = ( $i + $offset ) % $c;
          echo $search[$idx] . ' =&gt; ' . $replace[$idx] . "<br>\n";
        }
        
        // result:
        // c => j
        // d => y
        // e => k
        // a => g
        // b => w
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-10-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-05-31
          • 1970-01-01
          • 2022-06-30
          • 2021-09-30
          相关资源
          最近更新 更多