我在PHP中有一个大型数组。
它包含使用下划线分割为一种类别的字符串:
category1_property
category1_category2_category3
category2_category3_category4_category5
我有一个名为
的函数array get_values($prefix)
返回以给定前缀开头的数组的所有值,例如
get_values("category2_category3_");
这个函数foreach()每次遍历整个数组,收集所有以前缀开头的字符串,即一个简单的
foreach ($my_array as $line)
if (substr($line, 0, strlen($prefix)) == $prefix))
array_push ($result, $line);
我在表现方面做得很糟糕,特别是看到每个请求执行此操作数十次。
有没有人知道如何加快速度,而不必采用完全不同的方式存储数据?
使用数据库可能既快又聪明,但我想避免这种情况。数据来自文件,我无法将其移植到数据库。
将构造预先排序或拆分为多维数组或对象不是一种选择,因为我有时需要查询类别名称的部分(例如“category1_ca *”)
提前感谢任何输入。
答案 0 :(得分:1)
对于节省时间的访问,我认为最简单的解决方案是对数组进行排序,并使用binary search algorithm的修改变体来查找与查询匹配的较低和较高数组边界。这是有效的,因为具有相似前缀的字符串总是按顺序排序。
获得此范围后,获取匹配元素是一个简单的for循环。
显然这不是一项微不足道的任务,所以不要浪费任何时间在此,除非真的是性能问题。过早优化,你知道钻...
答案 1 :(得分:1)
我不清楚get_values函数应该匹配什么 - 无论如何,这可能是您正在寻找的性能友好的解决方案?
function get_values($prefix) {
$included_array_from_file = array ( "category1_property", "category1_category2_category3", "category2_category3_category4_category5");
foreach($included_array_from_file as $val) {
if(strpos($val,$prefix)===0) {
$out[] = $val;
}
}
return $out;
}
print_r( get_values("category2_category3_") );
输出:
Array ( [0] => category2_category3_category4_category5 )
<强>更新强>
您需要计算字符串中出现“category2_category3_”的次数,对吗?在这种情况下,我建议您为完整字符串创建一个多维数组,并按照此示例中所示计算每个匹配项:(请注意,该示例仅说明了如何完成 - 示例当前失败,因为我不知道如何动态构建多维数组,在向数组添加项目时可能需要调用另一个“create array”函数。)
失败(“不能将标量值用作数组”) - 不确定如何使用。
$data = array("category1_property", "category1_category2_category3", "category2_category3_category4_category5");
$counter = array();
foreach($data as $val) {
foreach(explode(":",$val) as $val2) {
// Now, create a multi-dimensional array with the category items as keys and increment the value by one for each item in the string, as in this example:
// "category2_category3_category4_category5" ... turns into:
// $counter[category2] += 1;
// $counter[category2][category3] += 1;
// $counter[category2][category3][category4] += 1;
// $counter[category2][category3][category4][category5] += 1;
}
}
预期用途:
echo $counter[category2][category3];
答案 2 :(得分:1)
我认为你正在寻找preg_grep
答案 3 :(得分:1)
你真的限制了选项!即便如此,我认为预先分割数据可能是最佳选择。考虑:
前缀'cat1_cat2_cat3_dog'='fido'
,'cat1_cat2_cat3_fish'='goldie'
,'cat1_cat2_cat3_frog'='kermit
变为
$arr[cat1][cat2][cat3][dog]=fido
$arr[cat1][cat2][cat3][fish]=goldie
$arr[cat1][cat2][cat3][frog]=kermit
如果您希望所有内容都带有前缀cat1_cat2
:
$arr['cat1']['cat2']=array('cat3'=>array('dog'=>'fido','fish'=>'goldie'));
如果您希望所有内容都使用前缀cat1_cat2_cat3_f*
,则只需搜索$arr['cat1']['cat2']['cat3']
中的最后一个字词:
$matches=preg_grep("/^f/",array_keys($arr['cat1']['cat2']['cat3']));
foreach($matches as $k){
$results[]=$arr['cat1']['cat2]['cat3'][$k];
}
答案 4 :(得分:0)
或者你可以使用array_filter()的匿名函数:
function get_values($arr, $str)
{
$func = create_function('$item', 'return (strpos($item, "' . $str . '") === 0);');
return array_filter($arr, $func);
}
$prefix = 'category1';
$result = get_values($my_array, $prefix);