• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • array_combine()

    (PHP 5, PHP 7)

    创建一个数组,用一个数组的值作为其键名,另一个数组的值作为其值

    说明

    array_combine(array $keys,array $values): array

    返回一个array,用来自$keys数组的值作为键名,来自$values数组的值作为相应的值。

    参数

    $keys

    将被作为新数组的键。非法的值将会被转换为字符串类型(string)。

    $values

    将被作为Array的值。

    返回值

    返回合并的array,如果两个数组的单元数不同则返回FALSE

    错误/异常

    如果作为$keys的数组和作为$values的数组的元素个数不一样,将会抛出一个警告错误(E_WARNING)。

    更新日志

    版本说明
    5.4.0(修复)早期版本中如果是空数组就报E_WARNING的错并且返回FALSE

    范例

    一个array_combine()简单的例子

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

    以上例程会输出:

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

    参见

    If two keys are the same, the second one prevails. 
    Example:
    <?php
    print_r(array_combine(Array('a','a','b'), Array(1,2,3)));
    ?>
    Returns:
    Array
    (
      [a] => 2
      [b] => 3
    )
    But if you need to keep all values, you can use the function below:
    <?php
    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)));
    ?>
    Returns:
    Array
    (
      [a] => Array
        (
          [0] => 1
          [1] => 2
        )
      [b] => 3
    )
    Further to loreiorg's script 
    in order to preserve duplicate keys when combining arrays.
    I have modified the script to use a closure instead of create_function
    Reason: see security issue flagged up in the documentation concerning create_function
    <?php
    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;
    }
    ?>
    
    array_combine() has a strange bug/misfeature (as of PHP 5.3.2): There is no logical reason for <? array_combine(array(), array()) ?> throwing a warning and returning FALSE, instead of returning <? array() ?> (see http://bugs.php.net/bug.php?id=34857). Here is a quick workaround:
    <?php
    function array_real_combine($a, $b)
    {
      return $a===array() && $b===array() ? array() : array_combine($a, $b);
    }
    ?>
    
    <?php
    // If they are not of same size, here is solution:
    $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); 
    // Output
    // Array ( [AL] => Alabama [AK] => Alaska [AZ] => Arizona 
    // [AR] => Arkansas )
    ?>
    
    I recently had to flip an array and group the elements by value, this snippet will do that:
    <?php
    function flipAndGroup($input) {
      $outArr = array();
      array_walk($input, function($value, $key) use (&$outArr) {
        if(!isset($outArr[$value]) || !is_array($outArr[$value])) {
          $outArr[$value] = [];
        }
        $outArr[$value][] = $key;
      });
      return $outArr;
    }
    ?>
    Example:
    <?php
    $users_countries = array(
      'username1' => 'US',
      'user2' => 'US',
      'newuser' => 'GB'
    );
    print_r(flipAndGroup($users_countries));
    ?>
    Returns:
    Array
    (
      [US] => Array
        (
          [0] => username1
          [1] => user2
        )
      [GB] => Array
        (
          [0] => newuser
        )
    )
    I needed to read CSV files into associative arrays with column headers as keys. Then I ran into a problem when you have empty columns at the end of a row because array_combine returns false if both arrays don't have the same number of elements. This function based on quecoder at gmail's combine_arr() below allowed me to pad either array or not when parsing my CSVs to arrays.
    $a is the array of header columns and $b is an array of the current row retrieved with fgetcsv()
    <?php
    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);
    }
    ?>
    
    If two keys are the same, the second one prevails.
    Example:
    <?php
    print_r(array_combine(Array('a','a','b'), Array(1,2,3)));
    ?>
    Returns:
    Array
    (
      [a] => 2
      [b] => 3
    )
    This will seem obvious to some, but if you need to preserve a duplicate key, being you have unique vars, you can switch the array_combine around, to where the vars are the keys, and this will output correctly.
    This [default] formula auto-removes the duplicate keys.
    $i=0;
    foreach (array_combine($keys, $vars) as $key => $var)
    {
    $i=$i;
    echo($key);
    echo " ";
    echo($var);
    }
    This formula accomplishes the same thing, in the same order, but the duplicate "keys" (which are now vars) are kept.
    $i=0;
    foreach (array_combine($vars, $keys) as $var => $key)
    {
    $i=$i;
    echo($key);
    echo " ";
    echo($var);
    }
    I know, I'm a newbie, but perhaps someone else will need this eventually. I couldn't find another solution anywhere.
    I needed a function that truncated extra values, and only went as far as keys without throwing a warning as array_combine does.
    <?php
    function safeArrayCombine($keys, $values) {
      $combinedArray = array();
        
      for ($i=0, $keyCount = count($keys); $i < $keyCount; $i++) {
         $combinedArray[$keys[$i]] = $values[$i];
      }
        
      return $combinedArray;
    }
    ?>
    
    I needed a function that would take keys from one unequal array and combine them with the values of another. Real life application:
    Select 4 product types.
    Each product has a serial.
    There are 4 sets of products.
      <?php
        function array_combine2($arr1, $arr2) {
          $count1 = count($arr1);
          $count2 = count($arr2);
          $numofloops = $count2/$count1;
            
          $i = 0;
          while($i < $numofloops){
            $arr3 = array_slice($arr2, $count1*$i, $count1);
            $arr4[] = array_combine($arr1,$arr3);
            $i++;
          }
          
          return $arr4;
        }
      ?>
    Input:
    Array
    (
      [0] => SMART Board
      [1] => Projector
      [2] => Speakers
      [3] => Splitter
    )
    , Array
    (
      [0] => serial to smart board1
      [1] => serial to projector 1
      [2] => serial to speakers 1
      [3] => serials to splitter 1
      [4] => serials to smart board 2
      [5] => serials to projector 2
      [6] => serials to speakers 2
      [7] => serials to splitter 2
    )
    Array
    (
      [0] => Array
        (
          [SMART Board] => serial to smart board1
          [Projector] => serial to projector 1
          [Speakers] => serial to speakers 1
          [Splitter] => serials to splitter 1
        )
      [1] => Array
        (
          [SMART Board] => serials to smart board 2
          [Projector] => serials to projector 2
          [Speakers] => serials to speakers 2
          [Splitter] => serials to splitter 2
        )
    )
    I had an epiphany when try to handle NON-ASSOCIATIVE array forms in my controller. This little one liner can pretty much edit ANY kind of non-associative array. For example this one just returns an array of values inputed by a new user.
    The $data value is the the json_decoded() value of a register form.
    Here is used str_replace, you could definitely do a number of things like preg matches and other things. 
    $readyToProcessForUser = array_combine(str_replace("new_user_", "", array_keys($data)), $data);
    You could also do the same for the values.
    $readyToProcessForUser = array_combine(array_keys($data), str_replace("-", "", $data));
    Or BOTH!
    Use full if you don't want to walk an entire array and the keys through the same callback.
    $readyToProcessForUser = array_combine(array_walk('trim', array_keys($data)), array_walk('custom_callback', array_values($data)));
    $item = array();
    array_map(
      function($element) use($column_name,$key,&$item){
        $item[$element[$key]] = $element[$column_name];
      },
      $data
    );
    This is the function for PHP4 :
    <?php
    function array_combine($arr1,$arr2) {
      $out = array();
      foreach($arr1 as $key1 => $value1)  {
      $out[$value1] = $arr2[$key1];
      }
      return $out
    }
    ?>
    
    I was looking for a function that could combine an array to multiple one, for my MySQL GROUP_CONCAT() query, so I made this function.
    <?php
      function array_combine_array(array $keys)
      {
        $arrays = func_get_args();
        $keys = array_shift($arrays);
        
        /* Checking if arrays are on the same model (array('INDEX'=> array()) or array()) */
        $check = count(array_unique(array_map('is_array',array_map('current',$arrays)))) === 1;
        if (!$check) { trigger_error('Function array_combine_array() expects all parameters to be same type array or array of array',E_USER_NOTICE); return array(); }
        
        /* Checking the model of arrays, array('INDEX' => array()) or Array() */
        $assocArray = is_array(array_shift(array_map('current',$arrays)));
        
        /* If empty $Keys is given, we fill an empty array */
        if (empty($keys)) $keys = array_keys(array_fill(0,max(($assocArray) ? array_map('count',array_map('current',$arrays)) : array_map('count',$arrays)),'foo'));
        /* Init */
        $ret=array();$i=0;
        /* Cycling on each keys values, making an offset for each */
        foreach($keys as $v)
        {
          /* Cycling on arrays */
          foreach ($arrays as $k)
          {
            if ($assocArray)
            {
              /* Getting the index of the element */
              $key = key($k);
              /* If the offset exists, we place it */
              $ret[$v][$key] = isset($k[$key][$i]) ? $k[$key][$i]:false;
            }
            /* Making the array with auto-made index */
            else
              $ret[$v][] = isset($k[$i]) ? $k[$i]: false;
          }
          /* Getting the next offset */
          $i++;
        }
        return $ret;
      }
      /* Examples */
      $r = array(1,2,4,10);
      $a1 = array('one','two','four','ten');
      $a2 = array('un','deux','quatre','dix');
      $a3 = array('uno','dos','quatro','diez');
       
       print_r(array_combine_array($r,array('english' => $a1),array('french' => $a2),array('spanish' => $a3))); /* Associative index, associative subarray indexes */
       print_r(array_combine_array($r,$a1,array('french' => $a2),array('spanish' => $a3))); /* Ouputs Error */
       print_r(array_combine_array($r,$a1,$a2,$a3)); /* Associative index, auto-made subarray indexes */
       print_r(array_combine_array(array(),array('english' => $a1),array('french' => $a2),array('spanish' => $a3))); /* Auto-made index, associative subarray indexes */
    ?>
    
    Some tips for merging same values in an array
    <?php
    $array1 = array(1,2,3,4,5,6,7,8,9,10,11,12);
    $array2 = array(1,2,3,13);
    $merged = array_merge($array1,$array2);
    // output normal array_merge
    echo '<pre>After array_merge :
    ';
    print_r($merged);
    echo '</pre>';
    // do double flip for merging values in an array
    $merged = array_flip($merged);
    $merged = array_flip($merged);
    // Output after
    echo '<pre>After Double Flip : 
    ';
    print_r($merged);
    echo '</pre>';
    ?>
    Output ::
    After array_merge :
    Array
    (
      [0] => 1
      [1] => 2
      [2] => 3
      [3] => 4
      [4] => 5
      [5] => 6
      [6] => 7
      [7] => 8
      [8] => 9
      [9] => 10
      [10] => 11
      [11] => 12
      [12] => 1
      [13] => 2
      [14] => 3
      [15] => 13
    )
    After Double Flip : 
    Array
    (
      [12] => 1
      [13] => 2
      [14] => 3
      [3] => 4
      [4] => 5
      [5] => 6
      [6] => 7
      [7] => 8
      [8] => 9
      [9] => 10
      [10] => 11
      [11] => 12
      [15] => 13
    )
    Khaly's PHP4 code below does not work correctly in all cases. Consider when your array consists of floats:
    <?php
    $okay = array(0, 10, 20, 30);
    $not_okay = array(0, 0.5, 1, 1.5);
    $foo = array_combine($okay, $okay);
    $bar = array_combine($not_okay, $not_okay);
    /* 
    Results:
    $foo = {
     [0]=> int(0)
     [10]=> int(10)
     [20]=> int(20)
     [30]=> int(30)
    }
    $bar = {
     [0]=> float(0.5)
     [1]=> float(1.5)
    }
    */
    ?>
    What can you do? In my case, I was just zipping up some select-box options, so I converted everything in my floats to strings.
    Function eliminates the error Throws E_WARNING if the number of elements in keys and values ​​does not match.
    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 ));
    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
    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
    You can create an array hashset from a flat array, storing both keys and values, with array_combine(). This works with duplicate values in the array too.
    <?php
    $flat_array = array(
        'one',
        'two',
        'three',
        'three',
        'four',
        'one'
    );
    $set = array_combine($flat_array, $flat_array);
    var_dump($set);
    ?>
    This outputs the following:
    array(4) {
      ["one"]=>
        string(3) "one"
      ["two"]=>
        string(3) "two"
      ["three"]=>
        string(5) "three"
      ["four"]=>
        string(4) "four"
    }
    <?php
    /**
     * Return alternatives defined by values of each parameters.
     *
     * Exemple :
     *
     * array_alternatives(array('foo','bar'), array('baz', 'qux'));
     * array(
     *   array('foo', 'baz'),
     *   array('bar', 'baz'),
     *   array('foo', 'qux'),
     *   array('bar', 'qux'),
     * );
     * 
     * array_alternatives(array('a'), array('simple-minded'), array('solution'));
     * array(
     *   array('a', 'simple-minded', 'solution')
     * );
     * 
     * array_alternatives(array('a'), array('red', 'blue'), array('car'));
     * array(
     *   array('a', 'red', 'car'),
     *   array('a', 'blue', 'car'),
     * );
     * 
     * @param array $first_element
     * @param array $second_element
     * @return array
     * @author Xavier Barbosa
     */
    function array_alternatives(array $first_element, array $second_element)
    {
      $lists = func_get_args();
      $total_lists = func_num_args();
      
      for($i=0; $i<$total_lists; $i++)
      {
        $list =& $lists[$i];
        if (is_array($list) === FALSE)
          throw new Exception("Parameter $i is not an array.");
        if (count($list) === 0)
          throw new Exception("Parameter $i has no element.");
        unset($list);
      }
      
      // Initialize our alternatives
      $alternatives = array();
      foreach($lists[0] as &$value)
      {
        array_push($alternatives, array($value));
        unset($value);
      }
      unset($lists[0]);
      
      // Process alternatives
      for($i=1; $i<$total_lists; $i++)
      {
        $list =& $lists[$i];
        
        $new_alternatives = array();
        foreach($list as &$value)
        {
          foreach($alternatives as $_)
          {
            array_push($_, $value);
            array_push($new_alternatives, $_);
          }
        }
        
        // Rotate references, it's cheaper than copy array like `$alternatives = $new_alternatives;`
        $alternatives =& $new_alternatives;
        unset($new_alternatives, $list, $lists[$i]);
      }
      
      return $alternatives;
    }
    ?>
    
    This may be obvious, but I don't see anything about it on the manual page, so a friendly warning... The array you are using as keys must have all unique values. If not, array elements get dropped. 
    <?php
    $arr_notUnique = array('one' , 'one' , 'two');
    $arr_b = array('red' , 'green' , 'blue');
    $arr_combo = array_combine($arr_notUnique, $arr_b);
    ?>
    Results: Array ( [one] => green [two] => blue )
    NOT: Array ( [one] => red [one] => green [two] => blue )
    array_combine() returns NULL instrad of FALSE, when non-array parameters are given (issuing warning).
    <?php
     //NULL
     var_dump(array_combine('string',array(42)));
    ?>