5

結果の配列が最初の配列からの 2 つの項目に続いて 2 番目の配列からの 1 つの項目を持ち、このように繰り返されるように、2 つの配列をマージするエレガントな方法は何でしょうか?

配列 1 = A1、A2、A3、A4、A5 など

配列 2 = B1、B2、B3、B4、B5 など

結果 = A1、A2、B1、A3、A4、B2、A5、A6、B3 など

複数のカウンターを使用して for ループを使用して実行しようとしていますが、配列の長さが常に必要なだけ長くなったり短くなったりするかどうかはわかりません。私は興味があります: より良い方法はありますか?

これが私が現在行っていることの単純化されたバージョンです:

$x = 0, $y = 0;
for($i=0; $i<$total_num_blocks; $i++) {
    if ($i % 3) {   // if there's a remainder, it's not an 'every 3rd' item
        $result[$i] = $projects[$x++];
    } else {
        $result[$i] = $posts[$y++];
    }
}
4

4 に答える 4

4

この例は、$a および $b 配列のサイズに関係なく機能します。

<?php 

$a = ['A1', 'A2', 'A3', 'A4', 'A5'];
$b = ['BB1', 'BB2', 'BB3', 'BB4', 'BB5'];

for ($i = 0; $i < count($b); $i++) {
    array_splice($a, ($i+1)*2+$i, 0, $b[$i]);
}

echo "<pre>" . print_r($a, true) . "</pre>";

この例の出力は次のとおりです。

Array
(
    [0] => A1
    [1] => A2
    [2] => BB1
    [3] => A3
    [4] => A4
    [5] => BB2
    [6] => A5
    [7] => BB3
    [8] => BB4
    [9] => BB5
)

警告: キーは保存されません!

これは PHP 5.4.x のコードです。お持ちでない場合は、$a および $b 変数の [] を array() に置き換えてください。

于 2012-09-20T20:45:29.323 に答える
1
while( sizeof($posts) >= 2 && sizeof($projects) >= 1){
    array_push($result,
            array_shift($posts),
            array_shift($posts),
            array_shift($projects)
        );
}
# you will need to handle the case if $posts doesn't have an even number of elements    

注:これは$postsと$projectsを破壊します。

于 2012-09-20T20:28:41.630 に答える
0

エレガントなのか効率的なのかはわかりません。自分でベンチマークを実行する必要がありますが、ループなしでこれらの配列をマージする楽しい方法があります。

$a = array("a1","a2","a3","a4","a5","a6","a7","a8"); 
$b = array("b1","b2","b3","b4","b5","b6","b7","b8"); 

function asymmetricInterleave($a, $aCount, $b, $bCount) { 
    $ax = array_chunk($a, $aCount); 
    $bx = array_chunk($b, $bCount); 

    $diff = count($ax) - count($bx); 

    $remainder = array(); 
    if ($diff > 0) { 
        list($ax, $remainder) = array_chunk($ax, count($bx)); 
    } else if ($diff < 0) { 
        list($bx, $remainder) = array_chunk($bx, count($ax)); 
    } 

    $result = array_merge(array_map('array_merge', $ax, $bx), $remainder); 
    return call_user_func_array('array_merge', $result); 
} 


$result = asymmetricInterleave($a, 2, $b, 1); 
var_export($result); 
于 2012-09-21T11:08:20.863 に答える
0
   $array1 = array('A1','A2','A3','A4','A5','A6');
   $array2 = array('B1','B2','B3','B4','B5','B6');

   $resultArray = array();

   //Reverse Second Array
   $array2R = array_reverse($array2);

   for ($i = 0; $i < count($array1); $i++){
       $resultArray[] = $array1[$i];
       if (($i) % 2)
           $resultArray[] = array_pop($array2R);
   }

   var_dump($resultArray);

での結果

array(9) { [0]=> string(2) "A1" [1]=> string(2) "A2" [2]=> string(2) "B1" [3]=> string(2) "A3" [4]=> string(2) "A4" [5]=> string(2) "B2" [6]=> string(2) "A5" [7]=> string(2) "A6" [8]=> string(2) "B3"}

2 番目の配列を追跡する代わりに、2 番目の配列を逆にして、それを array_pop することができます。 http://php.net/manual/en/function.array-pop.php

array_pop() は、配列の最後の値をポップして返し、配列を 1 要素短くします。配列が空の場合 (または配列でない場合)、NULL が返されます。配列以外で呼び出されると、さらに警告が生成されます。

array2 の残りのすべての項目を結果の配列の最後に追加して、結果の配列を完成させることができます。

于 2012-09-20T20:40:23.200 に答える