我现在有四种方法可以提供。所有都可以通过更改$size 来修改以允许更大或更小的组。
- 2 创建“AB”、“CD”等
- 3 创建“ABC”、“DEF”等
- 4 创建“ABCD”、“EFGH”等
- 15 创建“ABCDEFGHIJKLMNO”、“PQRSTUVWXYZ”
Code#1 通过使用 2 个foreach() 循环和比较每个值的第一个字符将值作为数组处理。这是最容易理解的。
$fruits=array("date","guava","lemon","Orange","kiwi","Banana","apple");
natcasesort($fruits); // pre-sort them for alphabetized output
$size=3; // <-modify group sizes here
$chunks=array_chunk(range('A','Z'),$size); // 0=>["A","B","C"],1=>["D","E","F"],etc...
foreach($fruits as $fruit){
foreach($chunks as $letters){
if(in_array(strtoupper($fruit[0]),$letters)){ // check if captialized first letter exists in $letters array
$groups[implode($letters)][]=$fruit; // push value into this group
break; // go to next fruit/value
}
}
}
var_export($groups);
Code#2 将 apokryfos 非常聪明的 ord() 行与 Code#1 集成在一起,以消除内部循环(以及内部循环本身)的不匹配迭代。这提高了效率,但对可读性产生了负面影响。
$fruits=array("date","guava","lemon","Orange","kiwi","Banana","apple");
natcasesort($fruits); // pre-sort them for alphabetized output
$size=3; // <-modify group sizes here
$chunks=array_chunk(range('A','Z'),$size); // 0=>["A","B","C"],1=>["D","E","F"],etc...
foreach($fruits as $fruit){
$groups[implode($chunks[floor((ord(strtoupper($fruit[0]))-ord("A"))/$size)])][]=$fruit;
}
var_export($groups);
Code#3 使用 preg_match_all() 和一些过滤函数将值处理为 csv 字符串。这假设没有任何值在其中包含逗号。在我看来,由于所有的功能和非常长的正则表达式模式,这段代码很难一眼理解。
$fruits=array("date","guava","lemon","Orange","kiwi","Banana","apple");
natcasesort($fruits); // pre-sort them for alphabetized output // array(6 => 'apple',5 => 'Banana',0 => 'date',1 => 'guava',4 => 'kiwi',2 => 'lemon',3 => 'Orange')
$size=3; // <-modify group sizes here
$chunks=str_split(implode(range('A','Z')),$size); // ['ABC','DEF','GHI','JKL','MNO','PQR','STU','VWX','YZ']
$regex="/((?<=^|,)[".implode('][^,]*)|((?<=^|,)[',$chunks)."][^,]*)/i"; // '/((?<=^|,)[ABC][^,]*)|((?<=^|,)[DEF][^,]*)|((?<=^|,)[GHI][^,]*)|((?<=^|,)[JKL][^,]*)|((?<=^|,)[MNO][^,]*)|((?<=^|,)[PQR][^,]*)|((?<=^|,)[STU][^,]*)|((?<=^|,)[VWX][^,]*)|((?<=^|,)[YZ][^,]*)/i'
if(preg_match_all($regex,implode(",",$fruits),$out)){
$groups=array_map('array_values', // 0-index subarray elements
array_filter( // omit empty subarrays
array_map('array_filter', // omit empty subarray elements
array_combine($chunks, // use $chunks as keys for $out
array_slice($out,1) // remove fullstring subarray from $out
)
)
)
);
var_export($groups);
}
代码#4 将值作为不带循环或条件的数组处理,使用:array_map()、preg_grep()、array_values()、array_combine() 和 array_filter 形成一个-liner *折扣$size & $chunks 声明。 ...我不想停下来,直到我制作了一个单线 - 无论多么丑陋。 ;)
$fruits=array("date","guava","lemon","Orange","kiwi","Banana","apple");
natcasesort($fruits); // pre-sort them for alphabetized output
$size=3; // <-modify group sizes here
$chunks=str_split(implode(range('A','Z')),$size); // ['ABC','DEF','GHI','JKL','MNO','PQR','STU','VWX','YZ']
$groups=array_filter(array_combine($chunks,array_map(function($v)use($fruits){return array_values(preg_grep("/^[$v].*/i",$fruits));},$chunks)));
var_export($groups);
// $groups=array_filter( // remove keys with empty subarrays
// array_combine($chunks, // use $chunks as keys and subarrays as values
// array_map(function($v)use($fruits){ // check every chunk
// return array_values( // reset subarray's keys
// preg_grep("/^[$v].*/i",$fruits) // create subarray of matches
// );
// },$chunks)
// )
// );
所有代码输出相同的结果:
array (
'ABC' =>
array (
0 => 'apple',
1 => 'Banana',
),
'DEF' =>
array (
0 => 'date',
),
'GHI' =>
array (
0 => 'guava',
),
'JKL' =>
array (
0 => 'kiwi',
1 => 'lemon',
),
'MNO' =>
array (
0 => 'Orange',
),
)