【问题标题】:Mix two arrays but not shuffle?混合两个数组但不洗牌?
【发布时间】:2013-11-12 10:12:59
【问题描述】:

我想将两个数组合并/混合在一起,但我希望它是随机“混合”的,但不是随机的。例如:

$first = array(1,2,3,4);
$second = array(10,20,30,40);

可能的“混合”是:

$merged = array(1,10,20,30,2,40,3,4);
$merged = array(10,1,2,20,30,3,4,40);
$merged = array(1,2,3,10,20,4,30,40);

请注意,如果我们将这些值提取出来,我们仍然会得到以下的原始顺序:

1,2,3,4
10,20,30,40

在 php 中有快速的方法吗?

【问题讨论】:

  • 我想知道将这两个(使用array_combine)创建一个关联数组不是更好。
  • 你能定义randomly "mixed"和shuffle吗?

标签: php arrays sorting merge shuffle


【解决方案1】:

嗯,有(又一个)一种可能的方法:

$arr = call_user_func_array('array_merge', array_map(null, $first, $second));
print_r($arr); // [1, 10, 2, 20, 3, 30, 4, 40];

Demo。这显然是确定性的。对于随机排序,每对都应该另外洗牌。例如:

function zipShuffle($first, $second) {
  return call_user_func_array('array_merge', array_map(function($a, $b) {
    return mt_rand(0, 1) ? [$a, $b] : [$b, $a];
  }, $first, $second));
}

... 但这显然不能产生像[1,2,3,10,20...] 这样的东西。如果需要,这里有另一个解决方案:

function orderedShuffle($first, $second) {
  $results = [];
  $stor    = [$first, $second];
  $i       = mt_rand(0, 1);
  // switching between arrays on the fly
  while (list(, $v) = each($stor[$i])) {
    $results[] = $v;
    $i = mt_rand(0, 1);
  }

  // one array is gone, now we need to add all the elements
  // of the other one (as its counter left where it was)
  $i = 1 - $i;
  while (list(, $v) = each($stor[$i])) {
    $results[] = $v;
  }
  return $results;
}

Demo。最后一个函数实际上很容易扩展到任意数量的数组。

【讨论】:

  • 第二个作品就像一个魅力,漂亮干净,感谢演示!
【解决方案2】:

哼。也许这样的事情可能会奏效。

//Loop this shit until both arrays are done
$j = 0;
$i = 0;
$r = rand(0, 1);

if($r == 0) {
    $ret .= $array1[$i];
    $i++;
} else if($r == 1) {
    $ret .= $array2[$j];
    $j++;
}

当然你必须在这段代码中处理一些异常,但它可能是路由。

【讨论】:

    【解决方案3】:

    你可以试试这个,

        <?php 
    
    
            $first = array(1,2,3,4);
            $second = array(10,20,30,40);
    
            $arrayMixed=array();
            $firstReverse=array_reverse($first);
            $secondReverse=array_reverse($second);
    
            $firstReverseCount = count($firstReverse);
            $secondReverseCount = count($secondReverse);
    
            foreach($firstReverse as $key=>$val) {
                if ($firstReverseCount>0) { 
    
                        array_push($arrayMixed, array_pop($firstReverse));
    
                        if ($secondReverseCount>0) {
                            array_push($arrayMixed, array_pop($secondReverse));
                        }
    
                }
            }
            $ArrayMixeddata =  array_merge($arrayMixed, $second);       
    
    
            echo "<pre>";
                print_r($ArrayMixeddata);
            echo "</pre>";
    ?>
    

    【讨论】:

      【解决方案4】:

      不是快速的方法,但它们很有效。

          // with permutations
          function combineShuffleOrder($first, $second)
          {
              // combine into one array with alternation
              $firstLen = count($first);
              $secondLen = count($second);
              $max = max($firstLen, $secondLen);
              $result = array();
              for($i=0; $i < $max; $i++) {
                  if ($i < $firstLen)
                      $result[] = $first[$i];
                  if ($i < $secondLen)
                      $result[] = $second[$i];
              }
      
              // "shuffle" with permutation
              $len = count($result);
              for($i=1; $i<$len; $i++) {
                  if (rand(1, 3) % 2 == 0) {
                      $tmp = $result[$i-1];
                      $result[$i-1] = $result[$i];
                      $result[$i] = $tmp;
                      $i++; // skip one exchange
                  }
              }
              return $result;
          }
      
          // with using "shuffle" in subarray 
          function combineShuffleOrder2($first, $second)
          {
              // combine into one array with alternation
              $firstLen = count($first);
              $secondLen = count($second);
              $max = max($firstLen, $secondLen);
              $result = array();
              for($i=0; $i < $max; $i++) {
                  $sub = array();
                  if ($i < $firstLen)
                      $sub[] = $first[$i];
                  if ($i < $secondLen)
                      $sub[] = $second[$i];
                  shuffle($sub);
                  $result = array_merge($result, $sub);
              }
      
              return $result;
          }
      
          // with using "shuffle" in subarray if sources arrays are equals by length
          function combineShuffleOrder3($first, $second)
          {
              $max = count($first);
              $result = array();
              for($i=0; $i < $max; $i++) {
                  $sub = array(
                      $first[$i],
                      $second[$i]
                  );
                  shuffle($sub);
                  $result = array_merge($result, $sub);
              }
      
              return $result;
          }
      
          $first = array(1,2,3,4);
          $second = array(10,20,30,40);
          print_r(combineShuffleOrder($first, $second));
          print_r(combineShuffleOrder2($first, $second));
          print_r(combineShuffleOrder3($first, $second));
      

      【讨论】:

        猜你喜欢
        • 2014-02-23
        • 2018-10-31
        • 2015-04-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-31
        • 1970-01-01
        相关资源
        最近更新 更多