2017-09-21 27 views
1

假设一个PHP数组,转换为JSON时,具有以下格式:有效地找到基于属性值嵌套PHP数组元素

[{ 
    "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数组函数的最佳使用。

+0

它是一个JSON字符串? – Andreas

+0

有效,因为在microoptimize,或有效率作为内存使用,或有效,因为在代码中写的?它最初存在的JSON – mario

+0

@Andreas文本字符串,正确 –

回答

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 TWEAK:

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

查阅密钥对为[宽度=> 900,材料=>纸,...],因此:

$material = $keypairs['material']; 

我想补充一个array_key_exists以防万一。这样可以节省array_search(这不是一个很好的优势,但是您可能会使用密钥对象)。

如果你只需要一个值而没有别的值,性能是非常重要的,并且数组很大,我不会抛弃寻找'material'的想法:''在JSON中作为字符串strpos,即使它是一个代码味道。

+0

在10000次迭代中,这个函数更有效率,并且返回密钥对可以派上用场。我正在改变这个接受的答案,谢谢@ LSemi –

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); 
+0

感谢您的答案@Andreas,但我更喜欢Jigar的答案,它使用PHP数组函数 –

+0

当然。没问题。 – Andreas

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 
+0

辉煌的,我正在寻找的东西。我只是偶然发现了array_search/array_column技巧,但却无法正常工作。 –

+0

谢谢,很高兴帮助你:) –