我想创建一个在大型数组中搜索并返回一些字段的函数,例如,数组就像这样(大数组的var_dump
):
array(3) {
[0]=>
array(5) {
["group_id"]=>
int(87)
["group_name"]=>
string(28) "General Specifictaions"
["group_slug"]=>
string(80) "%da%af%d8%b2%db%8c%d9%86%d9%87-%d9%87%d8%a7%db%8c-%d8%b9%d9%85%d9%88%d9%85%db%8c"
["group_desc"]=>
string(0) ""
["attributes"]=>
array(4) {
[0]=>
array(5) {
["attr_id"]=>
int(95)
["attr_name"]=>
string(23) "Release date"
["attr_slug"]=>
string(67) "%d8%aa%d8%a7%d8%b1%db%8c%d8%ae-%d8%a7%d9%86%d8%aa%d8%b4%d8%a7%d8%b1"
["attr_desc"]=>
string(0) ""
["value"]=>
string(3) "144"
}
[1]=>
array(5) {
["attr_id"]=>
int(96)
["attr_name"]=>
string(21) "Availability"
["attr_slug"]=>
string(5) "stock"
["attr_desc"]=>
string(0) ""
["value"]=>
string(7) "instock"
}
}
}
[1]=>
array(5) {
["group_id"]=>
int(89)
["group_name"]=>
string(19) "Display"
["group_slug"]=>
string(55) "%d8%b5%d9%81%d8%ad%d9%87-%d9%86%d9%85%d8%a7%db%8c%d8%b4"
["group_desc"]=>
string(0) ""
["attributes"]=>
array(0) {
}
}
}
此数组是产品所有规格的列表,我想要做的是在attributes
部分中搜索特定属性并仅返回该属性,此搜索可以通过{{ 1}}或attr_id
或attr_name
,所以我创建了这个使用attr_slug
的函数,但我无法返回我想要的部分:
array_filter
它会过滤数组,但它不会返回我想要的部分,例如我希望结果像function dw_attr_value_by( $post_id = '', $field, $value ) {
if( !$post_id ){
global $post;
$post_id = $post->ID;
}
if( !$post_id ) return;
$table = dw_get_table_result( $post_id ); // The large array
return array_filter( $table, function( $v, $k ) use( $field, $value ){
$attributes = $v['attributes'];
if( sizeof( $attributes ) == 0 ) return;
for( $i = 0; $i < sizeof( $attributes ); $i++ ) {
if( $field == 'id' ) {
if( $attributes[$i]['attr_id'] == $value ) break;
} elseif( $field == 'slug' ){
if( $attributes[$i]['attr_slug'] == rawurlencode( $value ) ) break;
} elseif( $field == 'name' ){
if( $attributes[$i]['attr_name'] == $value ) break;
}
}
return $attributes[$i];
}, ARRAY_FILTER_USE_BOTH );
}
:
var_dump( dw_attr_value_by( $post->ID, 'id', 144 )
大型数组的JSON格式
array(5) {
["attr_id"]=>
int(95)
["attr_name"]=>
string(23) "Release date"
["attr_slug"]=>
string(67) "%d8%aa%d8%a7%d8%b1%db%8c%d8%ae-%d8%a7%d9%86%d8%aa%d8%b4%d8%a7%d8%b1"
["attr_desc"]=>
string(0) ""
["value"]=>
string(3) "144"
}
答案 0 :(得分:2)
我不认为array_filter是一种正确的方法。但是,您只需要在回调函数之外创建一个变量,并在那里保存过滤后的数据。
$foundAttrs = [];
$filteredArray = array_filter( $table, function( $v, $k ) use( $field, $value, $foundAttrs){
$attributes = $v['attributes'];
if( sizeof( $attributes ) == 0 ) return;
for( $i = 0; $i < sizeof( $attributes ); $i++ ) {
if( $field == 'id' ) {
if( $attributes[$i]['attr_id'] == $value ) break;
} elseif( $field == 'slug' ){
if( $attributes[$i]['attr_slug'] == rawurlencode( $value ) ) break;
} elseif( $field == 'name' ){
if( $attributes[$i]['attr_name'] == $value ) break;
}
}
array_push($foundAttrs, $attributes[$i]);
return $attributes[$i];
}, ARRAY_FILTER_USE_BOTH );
//now $foundAttrs consists of all found values
如果您发布原始数组(例如json字符串),那么更容易想出更好的想法,因为现在测试可能的解决方案并不容易
<强>更新强>
首先谈谈发布的问题代码:
sizeof($attributes)
),循环就会执行该命令
每次迭代return $attributes[$i];
将只返回$ attributes的最后一个元素所以我修复了这些要点,并在foreach循环的帮助下重写了这个函数。如果它不起作用,请将给定的数组(大数组)作为json字符串发布,这样我就能用真实数据测试我的解决方案
function dw_attr_value_by( $post_id = '', $field, $value ) {
if( !$post_id ){
global $post;
$post_id = $post->ID;
}
if( !$post_id ) return;
$table = dw_get_table_result( $post_id ); // The large array
foreach($table as $groupKey => $group) {
if (isset($group['attributes'])) {
foreach ($group['attributes'] as $attr) {
if( $field == 'id' && $attr['attr_id'] == $value) {
return $attr;
} elseif( $field == 'slug' && $attr['attr_slug'] == rawurlencode($value)){
return $attr;
} elseif( $field == 'name' && $attr['attr_name'] == $value){
return $attr;
}
}
}
}
return null;
}