PHPのお勉強!

PHP TOP

array_combine

(PHP 5, PHP 7, PHP 8)

array_combine 一方の配列をキーとして、もう一方の配列を値として、ひとつの配列を生成する

説明

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

keys 配列の値をキーとして、また values 配列の値を対応する値として生成した 配列 を作成します。

パラメータ

keys

キーとして使用する配列。無効な値を渡すと文字列に変換されます。

values

値として使用する配列。

戻り値

作成した配列を返します。

エラー / 例外

PHP 8.0.0 以降では、keys および values の要素数が一致しなかった場合は ValueError がスローされます。 それより前のバージョンでは、 E_WARNING が発生していました。

変更履歴

バージョン 説明
8.0.0 それぞれの配列の要素数が一致しなかった場合、 array_combine()ValueError をスローするようになりました。 これより前のバージョンでは、false を返していました。

例1 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
)

参考

  • array_merge() - ひとつまたは複数の配列をマージする
  • array_walk() - 配列の全ての要素にユーザー定義の関数を適用する
  • array_values() - 配列の全ての値を返す
  • array_map() - 指定した配列の要素にコールバック関数を適用する

add a note

User Contributed Notes 13 notes

up
117
loureirorg at gmail dot com
11 years ago
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
)
up
14
welcome at el hyphen mustafa
9 years ago
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;
}

?>
up
13
claude dot pache at gmail dot com
14 years ago
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);
}
?>
up
13
quecoder at gmail
16 years ago
<?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 )
?>
up
6
zequez at gmail dot com
13 years ago
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
)
up
3
dejiakala at gmail dot com
13 years ago
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);
}
?>
up
2
bradentkeith at dot dontspam dot gmail dot com
14 years ago
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
)

)
up
1
ilanfir at gmail dot com
9 years ago
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
)
)
up
-1
info at callismart dot com dot ng
4 months ago
As of PHP 8.0, array_combine throws ValueError if the number of elements for each array is not equal;

To be on a safer side, you can perform a check instead.

$arrayk = array( 'key1', 'key2', 'key3' );
$arrayv = array( 'v1', 'v2', 'v3' );

if ( count( $arrayk ) === count( $arrayv ) ) {
echo '<pre>';
var_dump( array_combine( $arrayk, $arrayv ) );
echo '</pre>';
} else {
return false;
}
up
0
PHPNewbie
7 years ago
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.
up
0
g.REMOVETHIS.vincendon AT vithemis.com
12 years ago
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 */
?>
up
0
Dan LaManna
13 years ago
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;
}
?>
up
-1
douglasrich9215 at gmail dot com
6 years ago
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)));