我有一个像这样的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
会占用大量资源,并且会降低速度。
是否有更多“直接”且资源占用更少的方式来获取每个对应的值?
答案 0 :(得分:3)
foreach占用大量资源,并且会减慢速度,因为它会复制输入数组并与此副本一起使用。如果要避免这种行为,可以使用指针访问。例如,您可以使用reset
,next
和current
构造来处理指针
$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