dtvnbe1428 2017-09-21 06:23
浏览 48
已采纳

根据属性值有效地找到嵌套的PHP数组元素

Suppose a PHP array, when cast to JSON, has the following format:

[{
    "key": "width",
    "value": "1200",
    "label": "Width (mm)",
    "choice": ""
},
{
    "key": "height",
    "value": "900",
    "label": "Height (mm)",
    "choice": ""
},
{
    "key": "material",
    "value": "paper",
    "label": "Material",
    "choice": "Paper"
}]

(This is a shortened version of the original, which can have many more elements)

Let's suppose I want to efficiently find what material is used. In other words, I want to search for a nested array that has for key the value material, and I want to return the value which would be paper.

I know this can be done by using a foreach/while loop, but PHP is rich with compiled array functions that I'm not very familiar with. What's the best function to use here?


UPDATE: What I've tried so far

Here's two things I've tried so far:

Attempt #1:

$json = '[{"key":"width","value":"1200","label":"Width (mm)","choice":""},{"key":"height","value":"900","label":"Height (mm)","choice":""},{"key":"material","value":"paper","label":"Material","choice":"Paper"}]';
$array = json_encode($json, true);
$material = '';
foreach($array as $nestedArray) {
  if($nestedArray['key'] = 'material') {
    $material = $nestedArray['value'];
  }
}

Attempt #2:

$json = '[{"key":"width","value":"1200","label":"Width (mm)","choice":""},{"key":"height","value":"900","label":"Height (mm)","choice":""},{"key":"material","value":"paper","label":"Material","choice":"Paper"}]';
$array = json_decode($json, true);
$filteredArray = array_filter($array, function($array) {
    return ($array['key'] == 'material');
});
$arr = array_pop($filteredArray)['value'];

Both produce the right value, but #1 is messy, and #2 may not be the best use of PHPs array functions.

  • 写回答

3条回答 默认 最新

  • duanji4870 2017-09-21 06:56
    关注

    It depends on what you want to do in addition to "finding the value". And what you have.

    array_filter is simple, but it will loop through the whole array.

    array_search on a reduced set looks faster, but it needs to make a copy of the source array, so it's actually slower than array_filter (not by much).

    The foreach solution you tried first will not create extra arrays and it allows you to break on a find:

    foreach($array as $nestedArray) {
        if ($nestedArray['key'] == 'material') {
            $material = $nestedArray['value'];
            break; // <--- found!
        }
    }
    

    So on short arrays I'd go with the accepted solution using array_column, or if you're sure that the material is there, there is this array_column tweak:

    // Transform the records into keypairs
    $keypairs = array_column($records, 'value', 'key');
    

    Now keypairs is [ width => 900, material => paper, ... ], so:

    $material = $keypairs['material'];
    

    I'd add a array_key_exists just to be sure. This saves the array_search (not that great an advantage, but you might have a use for the keypair object).

    If you need exactly that one value and nothing else, performance is at a premium, and the array is large, I'd not throw out the idea of looking for '"material":"' inside the JSON as a string with strpos, even if it's a code smell.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 使用ue5插件narrative时如何切换关卡也保存叙事任务记录
  • ¥20 软件测试决策法疑问求解答
  • ¥15 win11 23H2删除推荐的项目,支持注册表等
  • ¥15 matlab 用yalmip搭建模型,cplex求解,线性化处理的方法
  • ¥15 qt6.6.3 基于百度云的语音识别 不会改
  • ¥15 关于#目标检测#的问题:大概就是类似后台自动检测某下架商品的库存,在他监测到该商品上架并且可以购买的瞬间点击立即购买下单
  • ¥15 神经网络怎么把隐含层变量融合到损失函数中?
  • ¥15 lingo18勾选global solver求解使用的算法
  • ¥15 全部备份安卓app数据包括密码,可以复制到另一手机上运行
  • ¥20 测距传感器数据手册i2c