确定Array中最常见的扩展名

时间:2011-05-02 01:12:55

标签: php regex arrays sorting loops

考虑以下代码:

$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()不是防弹的......有什么想法吗?

2 个答案:

答案 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;
}

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