给定一个数组,如:
$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
与这种情况无关,但在我使用该函数的其他情况下。
第三种和第四种方法是前一种方法的混合。在这一点上,我原来的方法仍然是最快的,但是当我在几百或几千个单词上运行我的函数时,操作仍然会花费几十秒。关于如何提高在这种情况下获得复数单数的性能的任何建议?