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);
}
?>
array_combine
(PHP 5)
array_combine — 一方の配列をキーとして、もう一方の配列を値として、ひとつの配列を生成する
説明
array array_combine
( array $keys
, array $values
)
keys 配列の値をキーとして、また values 配列の値を対応する値として生成した 配列 を作成します。
パラメータ
- keys
-
キーとして使用する配列。無効な値を渡すと文字列に変換されます。
- values
-
値として使用する配列。
返り値
作成した配列を返します。 互いの配列の要素の数が合致しない場合に FALSE を返します。
エラー / 例外
keys および values の要素数が一致しなかった場合は E_WARNING が発生します。
変更履歴
| バージョン | 説明 |
|---|---|
| 5.4.0 | これまでのバージョンでは、空の配列に対しては E_WARNING を発生させて 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
)
dejiakala at gmail dot com
26-Oct-2011 09:32
Dan LaManna
17-Sep-2011 02:12
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;
}
?>
zequez at gmail dot com
27-Mar-2011 09:51
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
)
claude dot pache at gmail dot com
12-May-2010 04:04
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);
}
?>
bradentkeith at dot dontspam dot gmail dot com
01-Apr-2010 06:20
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
)
)
xavier at api-meal dot eu
22-Sep-2009 09:37
<?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;
}
?>
quecoder at gmail
25-Aug-2008 06:00
<?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 )
?>
J.D.D.
09-Aug-2008 07:31
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 )
Zoran
01-Apr-2008 10:57
Also, Khalys function only works if keys of both arrays are the same because array_combine ignores keys. An easy way to ignore them is by taking array_values(). Floats can be casted to strings to avoid overwriting.
So, the PHP4 function could look something like this:
<?php
function array_combine($arr1, $arr2) {
$out = array();
$arr1 = array_values($arr1);
$arr2 = array_values($arr2);
foreach($arr1 as $key1 => $value1) {
$out[(string)$value1] = $arr2[$key1];
}
return $out;
}
?>
Mike Jean
18-Mar-2008 03:59
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.
Khaly
03-Oct-2007 08:11
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
}
?>
neoyahuu at yahoo dot com
19-Mar-2007 02:36
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
)
ifeghali at interveritas dot net
26-Feb-2005 03:53
Use that code to group an array by its first element.
<?
function groupbyfirst($array)
{
foreach ($array as $row)
{
$firstkey = array_keys($row);
$firstkey = $firstkey[0];
$key = $row[$firstkey];
unset($row[$firstkey]);
$newarray[$key][] = $row;
}
return $newarray;
}
?>
Example:
<?
$array =
Array(
0 => Array('color' => 'red','name' => 'apple', 'quantity' => '3'),
1 => Array('color' => 'green','name' => 'pear', 'quantity' => '2'),
2 => Array('color' => 'yellow','name' => 'corn', 'quantity' => '3'),
3 => Array('color' => 'blue','name' => 'grape', 'quantity' => '4'),
4 => Array('color' => 'yellow','name' => 'banana', 'quantity' => '13'),
);
$output = groupbyfirst($array);
print_r($output);
?>
will return:
Array
(
[red] => Array ( [0] => Array ( [name] => apple [quantity] => 3 ) )
[green] => Array ( [0] => Array ( [name] => pear [quantity] => 2 ) )
[yellow] => Array ( [0] => Array ( [name] => corn [quantity] => 3 ), [1] => Array ( [name] => banana [quantity] => 13 ) )
[blue] => Array ( [0] => Array ( [name] => grape [quantity] => 4 ))
)
Or you can use mysql recordset:
<?
while ($row=mysql_fetch_array($result,MYSQL_ASSOC))
{
$firstkey = array_keys($row);
$firstkey = $firstkey[0];
$key = $row[$firstkey];
unset($row[$firstkey]);
$newarray[$key][] = $row;
}
?>
aidan at php dot net
20-May-2004 01:15
This functionality is now implemented in the PEAR package PHP_Compat.
More information about using this function without upgrading your version of PHP can be found on the below link:
http://pear.php.net/package/PHP_Compat
