2012-09-20 25 views
5

¿cuál sería una manera elegante de unir dos matrices, de modo que la matriz resultante tenga dos elementos del primer conjunto seguido de un único elemento del segundo conjunto, repitiendo de esta manera?Manera elegante de combinar asimétricamente 2 matrices en PHP

array 1 = A1, A2, A3, A4, A5, etc.

matriz 2 = B1, B2, B3, B4, B5, etc.

resultado = A1, A2, B1, A3, A4, B2, A5, A6, B3, etc.

Estoy tratando de hacerlo utilizando un bucle for con múltiples contadores, pero no sé si las longitudes de la matriz siempre serán tan largas o tan largas corto según sea necesario. Tengo curiosidad: ¿hay una mejor manera?

Aquí es una versión simplificada de lo que estoy haciendo actualmente:

$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++]; 
    } 
} 
+1

¿Cuál debe ser el resultado , si a) array1 tiene más O b) menos elementos que array2? –

+0

¿Se deberían preservar las claves? –

+0

sí, buena pregunta. no, no me importan las teclas de matriz; también si una matriz es más larga que la otra, $ result puede simplemente detenerse cuando una matriz está vacía, O contener el resto de la matriz más larga. Extrañamente, ambas opciones estarían bien para mi caso de uso particular. – wes

Respuesta

4

Este ejemplo funcionará independientemente de la $ ay $ b tamaño de la matriz.

<?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>"; 

salida de este ejemplo es:

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

Advertencia: Las llaves no se conservan!

Este es el código PHP 5.4.x, si no lo tiene, reemplace [] con matriz() en las variables $ a y $ b.

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  

Nota: Este es destructivo de $ postes y proyectos $.

+0

ah, eso es más elegante, gracias. También me gusta que el código esté estructurado de manera que sea más representativo del arreglo que estoy tratando de compilar – wes

+0

El único inconveniente es que $ publicaciones pueden ser un número impar, o si le importa mantener el contenido de $ publicaciones y $ proyectos (pero podrías copiar las matrices antes ...) – Lathan

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); 

Los resultados con

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"} 

En lugar de hacer el seguimiento de la segunda matriz, se puede invertir la segunda matriz, y array_pop ella. http://php.net/manual/en/function.array-pop.php

array_pop() aparece y devuelve el último valor de la matriz, acortando la matriz en un elemento. Si la matriz está vacía (o no es una matriz), se devolverá NULL. Además, producirá una advertencia cuando se llame a un no-array.

Es posible que desee finalizar la matriz resultante agregando todos los elementos restantes de la matriz2 al final de la matriz resultante.

0

No sé si es elegante o eficiente, tiene que ejecutar algún punto de referencia por sí mismo, pero no es una forma divertida de combinar esos arreglos sin bucles:

$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); 
Cuestiones relacionadas