在php中查找关联数组中值的索引?

5
如果您有一个在循环中填充的数组$p,格式如下:
$p[] = array( "id"=>$id, "Name"=>$name);

什么是在Name键中搜索John并返回$p索引的最快方法?除了循环遍历$p之外,还有其他方法吗?
我需要在$p中查找高达5000个名称,$p也可能包含5000行。目前,我通过循环遍历$p来查找每个名称,如果找到,则解析它(并将其添加到另一个数组中),从$p中删掉该行,并停止循环,准备开始查找下一个5000个名称之一。
我想知道是否有比遍历$p更快地获取索引的方法,例如类似于isset的方法?
谢谢大家阅读。

你必须循环。PHP内部不维护任何哈希映射或类似的值;只维护键。 (虽然您可以创建一个额外的数组,其类型为$q[$p[$key]] = $key; - bwoebi
唯一的方法是创建另一个关联数组,其中包含所有名称和索引(如果名称不唯一,则为索引数组),以便于在 $p 中查找每个名称的位置。您需要将该数组与 $p 一起维护。 - Tum
@GeorgePHP FYI,数据库不是唯一的数据源。 :) - Leri
不妨考虑只存储一个简单的列表(list()),而不是存储一个数组的数组。使用http://php.net/manual/en/function.list.php函数可以完全满足您的需求,并且更容易获取数据。 - Dave
1
@leri 内存表或临时表几乎和直接在内存中完成操作一样快,但如果源数据最初不在数据库中,我仍然不会费心。尽管在大型系统上使用数据库表有很多好处,但5000条记录只是很小的数量,所以完全可以在内存中完成操作,速度已经足够快了。 - Dave
显示剩余3条评论
3个回答

5

我看到这个问题的情况是,你有独特的id,但名称可能不是唯一的。

你可以将数组初始化为:

array($id=>$name);

你的搜索可以像这样:

array_search($name,$arr);

这将非常有效,因为在查找一根稻草中,本地方法有比你自己实现更好的实现。
例如:
$id = 2;
$name= 'Sunny';
$arr = array($id=>$name);
echo array_search($name,$arr);

Echoes 2

这种方法的主要优点是代码的可读性。


1
如果你知道需要在同一个请求中执行许多这些类型的搜索,则可以从它们创建一个索引数组。这将为每个需要创建的索引循环一次数组。
$piName = array();
foreach ($p as $k=>$v)
{
  $piName[$v['Name']] = $k;
}

如果您每页只需要执行一两次搜索,则考虑将数组移入外部数据库,并在那里创建索引。

虽然它看起来很适合查找第一个条目(当然,那将是相应的键),但如果OP需要在源数组中保留具有相同“名称”字段的多个条目,则不适用。 - Alma Do
它实际上会找到最后一个条目,这与OP当前的算法不同(该算法找到第一个)。 - Ignacio Vazquez-Abrams
啊,是的,我明白了。我的意思是 - 如果按照这种方式重构源数组,显然,这可能是丢失多个值的原因。因此,这种结构不能代替原始结构,但可以与其一起使用。 - Alma Do

0
$index = 0;
$search_for = 'John';
$result = array_reduce($p, function($r, $v) use (&$index, $search_for) {
  if($v['Name'] == $search_for) {
    $r[] = $index;
  }
  ++$index;
  return $r;
});

$result将包含$p中所有元素的索引,其中具有键Name且值为John。(当然,这仅适用于从0开始数字索引且索引中没有“空洞”的数组。)


编辑:可能更容易的方法是使用array_filter,但它不仅会返回索引,还会返回所有数组元素,其中Name等于John - 但索引将被保留:

$result2 = array_filter($p, function($elem) {
  return $elem["Name"] == "John" ? true : false;
});
var_dump($result2);

哪个更适合你的需求,或者哪个可能更快,这是你需要自己去弄清楚的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接