2011-05-02 32 views
2

看看下面的代码考虑:找出最常见的扩展在Array

$files = array('1.js', '1.css', '2.js', '2.css', '3.js', '3.png'); 
$extensions = array(); 

foreach ($files as $file) 
{ 
    $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION)); 

    if (empty($extensions[$extension]) === true) 
    { 
     $extensions[$extension] = 0; 
    } 

    ++$extensions[$extension]; 
} 

arsort($extensions); // array('js' => 3, 'css' => 2, 'png' => 1) 

$common_extension = key($extensions); // js 

的代码似乎工作,因为我希望它(我仍然需要检查发生了什么万一有一场平局,但这与这个问题无关)。我在寻找一种更有效的(和紧凑的方式)重写上面的代码中的,到目前为止,我已经得到了最接近的是:

$files = array('1.js', '1.css', '2.js', '2.css', '3.js', '3.png'); 
$extensions = array_count_values(array_map('strtolower', preg_replace('~^.*[.](.*)$~', '$1', $files))); 

arsort($extensions, SORT_NUMERIC); 

$common_extension = key($extensions); 

但这遍历数组的3倍,并且preg_replace()不是防弹... 有任何想法吗?

+0

我会使用普通的字符串函数,而不是正则表达式,如果你关心它。缺点是你最终会多出几行,因为你不能将数组传递给这些字符串函数。 – 2011-05-02 01:35:59

+1

您可以编写自己的方法,其中包含'strtolower'和''pathinfo'片段以用于'array_map'调用。这将为您节省一次迭代。如果你不想'array_count_values'再次运行数组,你必须再次指望你自己。 – Frank 2011-05-02 01:47:37

回答

0

我会做这样的事情:

<?php 
function getCommon($array, $result = array()) { 
    foreach ($array as $k => $v) { $array[$k] = strtolower(pathinfo($v, PATHINFO_EXTENSION)); } 
    $ext = array_count_values($array); arsort($ext,SORT_NUMERIC); 
    $k = array_keys($ext); $k0 = $k[0]; 
    if ($ext[$k0] > $ext[$k[1]]) { $result[] = $k0; } 
    else { foreach ($ext as $k => $v) { if ($v == $ext[$k0]) { $result[] = $k; } } } 
    return $result; 
} 

$files = array('1.js', '2.js', '3.png', '4.css'); 
print_R($files); 
print_R(getCommon($files)); 

$files2 = array('1.js', '2.js', '3.png', '4.png', '5.css'); 
print_R($files2); 
print_R(getCommon($files2)); 
?> 

这将返回一个数组,其中值是常用的扩展,即使他们有很多。

注意:当您的工作基本PHP功能可以完成时,请勿使用正则表达式 - 与php内置函数相比,regex太耗费资源。

+0

这似乎是做了我的第一个片段,但你正在循环阵列4次,我没有得到改善。 – 2011-05-02 13:14:31

+0

它也返回draws,它不使用正则表达式,它更短。 – Deele 2011-05-02 13:18:19

0

我已经考虑过这个问题很长一段时间了,我认为你的第一个片段几乎是它的答案。它不像更短的代码是更快的代码。该代码速度非常快,可以线性扩展到更大的阵列。这几乎是O(n)的复杂度加上排序算法0​​(我不知道它使用的是什么方法,但我希望它比自己写的更快)。我可以提供的唯一的事情是这个包含你的片段的小函数,并且在扩展不在数组中的情况下做一些调整。

function count_ext($array){ 
    $ret = array(); 
    foreach($array as $ext){ 
     $ext = strtolower(pathinfo($ext, PATHINFO_EXTENSION)); 
     if(!isset($ret[$ext])) $ret[$ext] = 0; 
     $ret[$ext]++; 
    } 
    arsort($ret); 
    return $ret; 
} 

我不知道你的数组有多少元素以及你的用例对时间有多重要,但是这种方法会很好。