考虑以下代码:
$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 :(得分: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内置函数相比,正则表达式太耗费资源。
答案 1 :(得分:0)
我已经考虑过这个问题很长一段时间了,我认为你的第一个片段就是它的答案。它不像更短的代码更快的代码。该代码非常快,并且可以线性扩展到更大的数组。它几乎是O(n)的复杂性加上排序算法arsort
(我不知道它使用的是什么方法,但我希望它比自写的方法更快)。我唯一可以提供的是这个包含你的片段的小函数,以及在扩展不在数组中的情况下的一些小调整。
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;
}
我不知道您的数组有多少元素以及您的用例对时间有多关键,但这种方法会很好。