Notatki PHP

prywatne zapiski na kamieniu

array_combine - tworzy tablicę, używając wartości z tablicy kluczy jako kluczy i wartości z tablicy wartości jako odpowiednich wartości. Klejenie tablic ze sobą.

array array_combine ( array $keys , array $values )

 
$a = array('green', 'red', 'yellow');
$b = array('avocado', 'apple', 'banana');
$c = array_combine($a, $b);
 
print_r($c);

Otrzymamy:

 
Array
(
    [green]  => avocado
    [red]    => apple
    [yellow] => banana
)

 

Identyczne klucze z tablicy będą gubione:

 
print_r(array_combine(Array('a','a','b'), Array(1,2,3)));

Otrzymamy:

 
Array
(
    [a] => 2
    [b] => 3
)

Rozwiązanie tego problemu:

 
function array_combine_($keys, $values)
{
    $result = array();
    foreach ($keys as $i => $k) {
        $result[$k][] = $values[$i];
    }
    array_walk($result, create_function('&$v', '$v = (count($v) == 1)? array_pop($v): $v;'));
    return    $result;
}
 
print_r(array_combine_(Array('a','a','b'), Array(1,2,3)));

gdzie otrzymamy:

 
Array
(
    [a] => Array
        (
            [0] => 1
            [1] => 2
        )
 
    [b] => 3
)

 

Ciekawe rozwiązanie w którym nie giną klucze i elementy:

 
// klucze
$tablica1 = array ("zielony", "czerwony", "niebieski", "czarny", "fioletowy");
 
// wartości
$records = array(
    array(
        'id' => 2135,
        'first_name' => 'Jaśko',
        'last_name' => 'Pawlak',
    ),
    array(
        'id' => 3245,
        'first_name' => 'John',
        'last_name' => 'Smith',
    ),
    array(
        'id' => 5342,
        'first_name' => 'Kaśka',
        'last_name' => 'Pawlaczka',
    ),
    array(
        'id' => 5623,
        'first_name' => 'Jack',
        'last_name' => 'September',
    )
);
 
 
 
 
 
function array_combine_($keys, $values){
    $result = array();
 
    foreach ($keys as $i => $k) {
     $result[$k][] = $values[$i];
     }
 
    array_walk($result, function(&$v){
     $v = (count($v) == 1)array_pop($v): $v;
     });
 
    return $result;
}
 
 
   $c = array_combine_($tablica1, $records);
    var_dump($c);
 

Otrzymamy nową tablicę:

 
array (5)
zielony => array (3)
 id => 2135
 first_name => "Jaśko" (6)
 last_name => "Pawlak" (6)
czerwony => array (3)
 id => 3245
 first_name => "John" (4)
 last_name => "Smith" (5)
niebieski => array (3)
 id => 5342
 first_name => "Kaśka" (6)
 last_name => "Pawlaczka" (9)
czarny => array (3)
 id => 5623
 first_name => "Jack" (4)
 last_name => "September" (9)
fioletowy => null

 

Teraz trochę skomplikujemy - mamy w tablicy przyszłych kluczy dwa identyczne elementy:

 
$tablica1 = array ("zielony", "czerwony", "niebieski", "czerwony", "fioletowy");

Polecenie:

 
  $c = array_combine_($tablica1, $records);
    var_dump($c);

da nam rezultat w postaci nowej tabeli, gdzie mamy dwa elementy dla koloru czerwony:

 
array (4)
zielony => array (3)
 id => 2135
 first_name => "Jaśko" (6)
 last_name => "Pawlak" (6)
czerwony => array (2)
 0 => array (3)
  id => 3245
  first_name => "John" (4)
  last_name => "Smith" (5)
 1 => array (3)
  id => 5623
  first_name => "Jack" (4)
  last_name => "September" (9)
niebieski => array (3)
 id => 5342
 first_name => "Kaśka" (6)
 last_name => "Pawlaczka" (9)
 fioletowy => null

 

array_combine zwraca wartość false, jeśli obie tablice nie mają tej samej liczby elementów.

 
 
function array_combine_special($a, $b, $pad = TRUE) {
    $acount = count($a);
    $bcount = count($b);
    // more elements in $a than $b but we don't want to pad either
    if (!$pad) {
        $size = ($acount > $bcount)$bcount : $acount;
        $a = array_slice($a, 0, $size);
        $b = array_slice($b, 0, $size);
    } else {
        // more headers than row fields
        if ($acount > $bcount) {
            $more = $acount - $bcount;
            // how many fields are we missing at the end of the second array?
            // Add empty strings to ensure arrays $a and $b have same number of elements
            $more = $acount - $bcount;
            for($i = 0; $i < $more; $i++) {
                $b[] = "";
            }
        // more fields than headers
        } else if ($acount < $bcount) {
            $more = $bcount - $acount;
            // fewer elements in the first array, add extra keys       
            for($i = 0; $i < $more; $i++) {
                $key = 'extra_field_0' . $i;
                $a[] = $key;
            }
 
        }
    }
 
    return array_combine($a, $b);
}

Inny przykład, gdy nasze tablice są bezczelnie różne:

 
$abbreviations = array("AL", "AK", "AZ", "AR", "TX", "CA");
$states = array("Alabama", "Alaska", "Arizona", "Arkansas");
function combine_arr($a, $b)
{
    $acount = count($a);
    $bcount = count($b);
    $size = ($acount > $bcount)$bcount : $acount;
    $a = array_slice($a, 0, $size);
    $b = array_slice($b, 0, $size);
    return array_combine($a, $b);
}
$combined = combine_arr($abbreviations, $states);
print_r($combined); 

Otrzymamy:

 
Array 
( 
[AL] => Alabama 
[AK] => Alaska 
[AZ] => Arizona
[AR] => Arkansas 
) 

 

Jeśli liczba elementów w kluczach i wartościach się nie zgadza, mogą posypać się ostrzeżenia. Rozwiązaniem może być funkcja:

 
function arrCombine($arr1 = array(),$arr2 = array()){
            if(is_array($arr1) && is_array($arr2)):
                $cntArr1 = count($arr1);
                $cntArr2 = count($arr2);
                $difference = max($cntArr1,$cntArr2) - min($cntArr1,$cntArr2);
                if($cntArr1 > $cntArr2):
                    for ($i=1;$i<=$difference;$i++){
                        $arr2[$cntArr2+$i] = $cntArr2 + 1;
                    }
                    return array_combine($arr1,$arr2);
                elseif($cntArr1 < $cntArr2):
                    for ($i=1;$i<=$difference;$i++){
                        $arr1[$cntArr1+$i] = count($arr1) + 1;
                    }
                    return array_combine($arr1,$arr2);
                else:
                    return array_combine($arr1,$arr2);
                endif;
            endif;
    }
$array = [1,4,5,6,7,8];
$array2 = ['john','smith'];
 
var_dump( arrCombine($array,$array2 ));

Otrzymamy:

 
array (size=6)
  1 => string 'john' (length=4)
  4 => string 'smith' (length=5)
  5 => int 3
  6 => int 3
  7 => int 3
  8 => int 3

Gdy: var_dump( arrCombine($array2,$array) );

 
array (size=6)
  'john' => int 1
  'smith' => int 4
  3 => int 5
  4 => int 6
  5 => int 7
  6 => int 8

 

 

Funkcja, która wytnie nadmiarowe elementy tabeli:

 
function safeArrayCombine($keys, $values) {
    $combinedArray = array();
 
    for ($i=0, $keyCount = count($keys); $i < $keyCount; $i++) {
         $combinedArray[$keys[$i]] = $values[$i];
    }
 
    return $combinedArray;
} 
 
$array = [1,4,5,6,7,8];
$array2 = ['john','smith'];
 
$c = safeArrayCombine($array2, $array);
 
array (2)
john => 1
smith => 4