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

时间:2017-09-21 06:23:09

标签: php arrays multidimensional-array

假设PHP数组在转换为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"
}]

(这是原版的缩短版,可以有更多元素)

假设我想要有效地找到使用的材料。换句话说,我想搜索一个key值为material的嵌套数组,并且我想返回value paper

我知道这可以通过使用foreach / while循环来完成,但PHP丰富了我不熟悉的编译数组函数。在这里使用的最佳功能是什么?

更新:到目前为止我尝试了什么

到目前为止,这是我尝试过的两件事:

尝试#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'];
  }
}

尝试#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'];

两者都产生正确的值,但#1是凌乱的,#2可能不是PHP数组函数的最佳用途。

3 个答案:

答案 0 :(得分:1)

如果它是你在评论中陈述的json文本,我的建议是正则表达式匹配。

这将找到“关键材料”和“值”并匹配值的值 它适用于小样本,但您必须在较大的字符串上尝试它。

https://regex101.com/r/CSTLUL/1

$re = '/key\": \"material\",.*?\"value\": \"(.*?)\",/s';
$str = '{
"key": "width",
"value": "1200",
"label": "Width (mm)",
"choice": ""
},
{
"key": "height",
"value": "900",
"label": "Height (mm)",
"choice": ""
},
{
"key": "material",
"value": "paper",
"label": "Material",
"choice": "Paper"
}]';

preg_match_all($re, $str, $matches);

// Print the entire match result
var_dump($matches);

答案 1 :(得分:1)

您可以使用array_searcharray_column的组合,因此无需使用循环

工作演示https://eval.in/865566

$data = '[{
    "key": "width",
    "value": "1200",
    "label": "Width (mm)",
    "choice": ""
},
{
    "key": "height",
    "value": "900",
    "label": "Height (mm)",
    "choice": ""
},
{
    "key": "material",
    "value": "paper",
    "label": "Material",
    "choice": "Paper"
}]';
$data = json_decode($data,True);


$key = array_search('material', array_column($data, 'key')); // get key of array
echo $data[$key]['value'];

输出

paper

答案 2 :(得分:1)

除了"找到值"之外,还取决于你想要做什么。你有什么。

array_filter很简单,但它会遍历整个数组。

缩小集上的

array_search看起来更快,但它需要制作源数组的副本,因此它实际上而不是array_filter(不是很多)。

您首先尝试的foreach解决方案不会创建额外的数组,它可以让您打破查找:

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

因此,在短数组中,我会使用array_column使用已接受的解决方案,或者如果您确定材料在那里,则会进行array_column调整:

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

现在密钥对是[width =&gt; 900,material =&gt;纸,...],所以:

$material = $keypairs['material'];

我只是为了确定添加array_key_exists。这样可以保存array_search(这不是一个很好的优势,但您可能会使用keypair对象。)

如果你只需要那个值而没有别的,那么性能是非常宝贵的,并且阵列很大,我并没有抛弃寻找&#39;&#34;材料&#34的想法;:&#34;&#39;在JSON中作为带strpos的字符串,即使它有代码味道。