2012-09-20 13 views
5

jaki byłby elegancki sposób łączenia dwóch tablic, tak, że wynikowa tablica ma dwa elementy z pierwszej tablicy, a następnie pojedynczy element z drugiej tablicy, powtarzając w ten sposób?Elegancki sposób asymetrycznego łączenia 2 tablic w PHP

Tablica 1 = A 1, A2, A3, A4, A5, itp

Tablica 2 = B1, B2, B3, B4, B5, itp

wyniku = A1, A2, B1, A3, A4, B2, A5, A6, B3, itp.

Próbuję to zrobić za pomocą pętli for z wieloma licznikami, ale nie wiem, że długość tablicy będzie zawsze taka sama lub równa krótki w razie potrzeby. Jestem ciekawy: czy istnieje lepszy sposób?

Oto uproszczona wersja tego, co mam aktualnie robi:

$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

Co powinno być wynikiem , jeśli a) tablica1 ma więcej OR b) mniej elementów niż tablica2? –

+0

Czy klucze powinny być zachowane? –

+0

tak, dobre pytanie. nie, nie dbam o klucze tablicy; również jeśli jedna tablica jest dłuższa od drugiej, wynik $ może się po prostu zatrzymać, gdy jedna tablica jest pusta, LUB zawiera resztę dłuższej tablicy. O dziwo, obie opcje byłyby w porządku w moim konkretnym przypadku użycia. – wes

Odpowiedz

4

Ten przykład będzie działał niezależnie od rozmiaru tablicy $ a i $ 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>"; 

Wyjście z tego przykładu jest:

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

Ostrzeżenie: klucze nie są zachowane!

To jest kod PHP w wersji 5.4.x, jeśli go nie masz, zamień [] na array() na zmienne $ a i $ 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  

Uwaga: To jest destrukcyjne $ $ stanowisk i projektów.

+0

ah, to jest bardziej eleganckie, dzięki. Podoba mi się również, że kod jest tak skonstruowany, że jest bardziej reprezentatywny dla tablicy, którą próbuję zbudować. – wes

+0

Jedynym minusem jest to, że $ post może być liczbą nieparzystą, lub jeśli zależy ci na utrzymaniu zawartości $ postów i $ projekty (ale możesz skopiować tablice przed ...) – 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); 

Wyniki z

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

Zamiast śledzenie drugiej tablicy, można odwrócić drugą tablicę, a array_pop go. http://php.net/manual/en/function.array-pop.php

array_pop() wyskakuje i zwraca ostatnią wartość tablicy, skracając tablicę o jeden element. Jeśli tablica jest pusta (lub nie jest tablicą), zwracana jest wartość NULL. Dodatkowo wygeneruje ostrzeżenie, gdy zostanie wywołany w tablicy.

Możesz chcieć zakończyć wynikową tablicę, dodając wszystkie pozostałe elementy z tablicy 2 na końcu tablicy wynikowej.

0

ja nie wiem, czy to jest eleganckie i wydajne, trzeba uruchomić jakiś punkt odniesienia przez siebie, ale nie jest to świetny sposób, aby połączyć te tablice bez pętli:

$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); 
Powiązane problemy