按字母范围对数组元素进行分组 [英] Group Array Elements by Letter Range

查看:116
本文介绍了按字母范围对数组元素进行分组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的数组,里面有一些名称,我想按它们的首字母分组。
例如所有以A到C作为第一个字母的名称都将排入一个数组,将D到F的名称都移到另一个,以此类推。

I have a simple array with some names in it and I want to group them by their first letter. E.g. all names with A to C as first letter go in an array and D to F go to another one and so on.

有没有比使用更好的方法了

Is there a better way to do it than using lots of if else?

推荐答案

我现在有四种方法可以提供。可以通过更改 $ size 将所有内容修改为允许更大或更小的组。

I now have four methods to offer. All can be modified to allow for larger or smaller groups by changing $size.


  • 2创建 AB, CD等。

  • 3创建 ABC, DEF等。

  • 4创建 ABCD, EFGH等。

  • 15创建 ABCDEFGHIJKLMNO, PQRSTUVWXYZ

  • 2 creates "AB","CD",etc.
  • 3 creates "ABC","DEF",etc.
  • 4 creates "ABCD","EFGH",etc.
  • 15 creates "ABCDEFGHIJKLMNO","PQRSTUVWXYZ"

代码#1 通过使用2个 foreach()循环并对每个值的第一个字符进行比较,将值作为数组处理。这是最容易理解的。

Code#1 processes the values as an array by using 2 foreach() loops and a comparison on the first character of each value. This is the easiest to comprehend.

$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);

代码#2 集成了apokryfos非常聪明的 ord()与Code#1行,以消除内部循环(和内部循环本身)的不匹配迭代。这样可以提高效率,但会对可读性产生负面影响。

Code#2 integrates apokryfos' very clever ord() line with Code#1 to eliminate the non-matching iterations of the inner loop (and the inner loop itself). This delivers improvement on efficiency, but a negative impact on readability.

$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);

代码#3 通过使用<$将值作为csv字符串处理c $ c> preg_match_all()和一些过滤功能。假设没有值包含逗号。我认为,由于所有功能和非常长的正则表达式模式,很难一眼就理解该代码。

Code#3 processes the values as a csv string by using preg_match_all() and some filtering functions. This assumes that no values include commas in them. In my opinion, this code is hard to comprehend at a glance because of all of the functions and the very long regex pattern.

$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 形成单线*折扣 $ size & $ chunks 声明。 ...我不愿意停下脚步,直到制造出单层纸面-无论多么难看。 ;)

Code#4 processes the values as an array without loops or conditionals by using: array_map(), preg_grep(), array_values(), array_combine(), and array_filter to form a one-liner *discounting the $size & $chunks declarations. ...I don't like to stop until I've produced a one-liner -- no matter how ugly. ;)

$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)
//            )
//        );

所有代码都输出相同的结果:

All codes output an identical result:

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',
  ),
)

这篇关于按字母范围对数组元素进行分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆