是否有比foreach更快的方式从JSON数组中获取值?

时间:2018-12-28 15:25:54

标签: php json

我有一个像这样的JSON数组:

[
  {"location":"1","distance":"25.75206"},
  {"location":"2","distance":"21.49343"},
  {"location":"3","distance":"24.13432"}
]

现在我正在对每个foreach做一个$location以获取相应的数据。

$locations = json_decode($locations, true);

foreach ($locations as $key => $value) {
  if ($value['location'] == $location) {
    $distance = $value['distance']; 
  }
}

问题在于,数组可能非常大,包含数千个项目,因此执行foreach会占用大量资源,并且会降低速度。

是否有更多“直接”且资源占用更少的方式来获取每个对应的值?

6 个答案:

答案 0 :(得分:3)

foreach占用大量资源,并且会减慢速度,因为它会复制输入数组并与此副本一起使用。如果要避免这种行为,可以使用指针访问。例如,您可以使用resetnextcurrent构造来处理指针

$value = reset($locations);
while ($element !== false)  {
    if ($value['location'] == $location) {
        $distance = $value['distance']; 
    }
    next($locations); 
    $value = current($locations);
}

当然,您可以在foreach中使用指针。例如:

foreach ($locations as $key => &$value) {
  if ($value['location'] == $location) {
    $distance = $value['distance']; 
  }
}

答案 1 :(得分:1)

我不是PHP专家,我不知道这是否适用于这里,但总的来说(不一定在所有情况下),如果您有一些清单并且知道大小或可以检测到终点,就可以进行迭代它并使用索引号访问每个项目(即list [0],list [1],list [2]等)。以这种方式遍历列表通常更快,但是我也不知道PHP,在这种情况下可能并非如此。

我还要补充一点,虽然我不知道您要在哪个环境中实现此功能,但在许多情况下,这实际上并不重要。使用多种语言的foreach实现通常是非常优化的。

答案 2 :(得分:1)

对我来说,您似乎有一个已知的位置,并且您正在尝试获取与该特定位置相关的信息。如果您可以通过使用的任何API(包括该API是您自己的代码)进行选择,那么我将尝试利用所述API /数据库查询该特定位置,而不是获取所有内容然后遍历它。

如果您别无选择,只能将JSON作为一个大数组获取,那么您有点不走运。为了加快后续“查询”的速度,您可能想做的一件事就是创建其索引对应于哪个位置的映射,或者是否仅按一个值(位置)查询以对数组重新索引。

$locations = json_decode($locations, true);
$locationsIndexedByLocation = [];
$distanceLocationMap = [];

foreach ($locations as $key => $value) {
  $locationsIndexedByLocation = [$value['location'] => $value];
  $distanceLocationMap = [$value['distance'] => $value['location']];
  if ($value['location'] == $location) {
    $distance = $value['distance']; 
  }
}

但是要小心创建大地图。您可以这样做来填补您的记忆。应该注意的是,这与“索引”列时关系数据库所做的非常相似。将这些位置对象缓存在可查询的数据库中可能是值得的。如果这些是从数据库中发出的,则应利用所述数据库,而不要尝试获取所有内容并过滤代码中的值。

此外,您似乎只从该循环中提取了一个$distance值。在这种情况下,如果您在循环中早些时候通过中断循环来获得比赛,则可以加快速度。

$locations = json_decode($locations, true);

foreach ($locations as $key => $value) {
  if ($value['location'] == $location) {
    $distance = $value['distance'];
    break;
  }
}

答案 3 :(得分:1)

您当前的格式意味着您必须搜索数据。如果您将其更改为具有位置作为属性名称,则可以直接访问它...

$locations = '{
"1":"25.75206",
"2":"21.49343",
"3":"24.13432"
}';
$locations = json_decode($locations, true);
echo $locations[3];

或者如果您想保留当前数据(更详细)...

$locations = '{
"1":{"location":"1","distance":"25.75206"},
"2":{"location":"2","distance":"21.49343"},
"3":{"location":"3","distance":"24.13432"}}
';
$locations = json_decode($locations, true);
echo $locations[3]['distance'];

答案 4 :(得分:1)

如果JSON结构与OP中显示的结构相同,则可以使用正则表达式从JSON查找目标值,而无需使用json_decode对其进行解析并迭代结果数组。

regex pattern匹配的JSON对象具有等于location的{​​{1}}键。

$location

检查针对if (preg_match("/\{\s*\"location\"\s*:\s*\"{$location}\".*?}/", $json, $match)){ $locations = json_decode("[{$match[0]}]", true)[0]; $distance = $locations['distance']; } 的正则表达式的性能并循环进入demo

答案 5 :(得分:0)

只需提取module Modal = type Message<'childModel, 'childMessage> = | Confirm of 'childModel | Cancel | ChildMessage of 'childMessage type Model<'T> = { Display : bool; Title : string; Child : 'T } let inline valid (x: ^t) = (^t: (static member valid: ^t -> bool) (x)) type Component<'T, ^childModel, 'childMessage when 'T :> ElmishComponent< ^childModel, 'childMessage> and ^childModel : (static member valid: ^childModel -> bool)>() = inherit ElmishComponent<Model<'childModel>, Message<'childModel, 'childMessage>>() // Error is highlighted on this line override this.View model dispatch = cond model.Display <| function | true -> div [ attr.style (if model.Display then "background: lightblue;" else "background: grey;") ] [ h3 [] [ text model.Title ] ecomp<'T,_,_> model.Child (dispatch << ChildMessage) p [] [] button [ // This is where I use the valid function attr.disabled (if valid model.Child then null else "true") on.click (fun _ -> dispatch <| Confirm model.Child) ] [ text "Confirm" ] button [ on.click (fun _ -> dispatch Cancel) ] [ text "Cancel" ] ] | false -> empty 值并在distance值上建立索引,然后访问location索引:

location