给出如下数组:
$nouns = array(
"man" => array("men"),
"octopus" => array("octopi", "octopuses"),
"ox" => array("oxen")
);
由大约3000个单数 - 复数对组成,如何通过调用array_search_loosely($nouns, "men")
来获得最有效的单数(密钥)?
然后我希望收到一个值为“man”的数组。
我尝试了四种不同的方法:
原始(使用函数array_is_assoc
,这是一个相当不言自明的,与情况无关)
function array_search_loosely($array, $values, $compare_keys = false) {
$values = is_array($values) ? $values : array($values);
foreach($array as $item_key => $item) {
if (is_array($item)) {
$return_key = true;
foreach($values as $value_key => $value) {
if (!in_array($value, $item)) {
$return_key = false;
break;
}
elseif($compare_keys === true and array_is_assoc($values)) {
if (!in_array($value_key, array_keys($item, $value))) {
$return_key = false;
break;
}
}
}
if ($return_key === true) {
$item_keys[] = $item_key;
}
}
elseif(!is_array($values)) {
if ($item === $values) {
$item_keys[] = $item_key;
}
}
}
return (isset($item_keys))? $item_keys : false;
}
第二种方法:
function array_search_loosely($array, $values, $compare_keys = false) {
$keys = array_keys(array_filter($array, function($item) use ($values, $compare_keys) {
return (!is_array($item) and $item === $values) or (is_array($item) and each_in_array($item, array_create($values), $compare_keys));
}));
return !empty($keys) ? $keys : false;
}
function each_in_array($array, $values, $compare_keys = false) {
return $compare_keys === false ? count(array_uintersect($values, $array, function($item1, $item2) { return $item1 === $item2 ? 0 : ($item1 > $item2 ? 1 : -1); })) == count($values) : count(array_uintersect_assoc($values, $array, function($item1, $item2) { return $item1 === $item2 ? 0 : ($item1 > $item2 ? 1 : -1); })) == count($values);
}
我选择使用array_uintersect
,也允许数组为$items
,因为如果我要使用array_intersect,则会为每个数组$item
生成通知。此选项允许each_in_array()
检查数组$values
。
此外,第三个可选参数$compare_keys
与此情况无关,但在我使用该函数的其他情况下。
第三种和第四种方法是前述的混合物。此时我的原始方法仍然是最快的,但是当我在几百或几千个单词上运行我的功能时,操作仍将花费几十秒。关于如何在这种情况下提高复数的单数性能的任何建议?
答案 0 :(得分:0)
您当前格式的地图不适合进行查找。你还需要反转它:
$invert = array(
'men' => 'man',
'octopi' => 'octopus',
'octopuses' => 'octopus',
'oxen' => 'ox',
);
答案 1 :(得分:0)
$search = 'men';
$found = '';
foreach($nouns AS $noun => $values){
if(in_array($search, $values){
echo 'Found what we\'re looking for.';
$found = $nouns[$noun];
}
}
print_r($found);
答案 2 :(得分:0)
输出:
源:
<!DOCTYPE html>
<html>
<body>
<?php
$nouns = array (
"data" => array("data"),
"datum" => array("data"),
"man" => array("men"),
"octopus" => array("octopi", "octopuses"),
"ox" => array("oxen"),
"hippopotamus" => array("hippopotami", "hippopotamuses")
);
function find_singular($nouns, $search)
{
foreach($nouns as $noun => $values)
{
if(in_array($search, $values))
{
$found[] = $noun;
}
}
if(!empty($found))
{
$n = count($found);
if($n > 1)
{
echo "<strong>$search</strong> has $n singular forms: <em>";
print_r(implode('</em> and <em>', $found).'</em><br />');
}
else
{
echo "<b>$search</b> is the plural of <em>$found[0]</em><br />";
}
}
else
{
echo "<b>$search</b> was not found.<br />";
}
}
find_singular($nouns, "men");
find_singular($nouns, "octopi");
find_singular($nouns, "data");
find_singular($nouns, "oxen");
find_singular($nouns, "octopuses");
find_singular($nouns, "hippopotami");
find_singular($nouns, "kittens");
?>
</body>
</html>
希望这有帮助!
编辑: 这样做的目的是什么?我猜你正在为网络或应用程序界面创建一个字典应用程序。只要您打算实施搜索功能,我认为您无法避免循环。你是否将整个字典存储在PHP数组中?我假设你是因为XML和mysql查询会花费更多的时间。我唯一的另一个建议是将字典拆分成你可以管理的数组(每个字母可能只有几十个),否则编写一个脚本来从现有字典数组或平面文件中生成这些数组,然后在你的实现中实现AJAX搜索框,类似于谷歌的预测搜索,但不是在键入搜索字符串时显示可能的结果,而是缩小要在后台静默搜索的数组。我有一个脚本,它可以做到这一点,如果这听起来可行,可以挖掘它。基本上,不是搜索整个字典(我已经看过一个超过一千二百万字!)每个关键字,到键入,发送和处理关键字时,循环周期可能会少得多。硬件也让人想起 - 服务器的硬盘,处理器和内存速度将占大多数。我也听说过C ++更适合字典搜索,对于PHP开发人员来说也不是太陌生的选择。