我想创建一个在大数组中搜索并返回一些字段的函数,该数组例如是这样的(大数组的 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
部分中搜索特定属性并仅返回该属性,并且此搜索可以是通过 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 )
:
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"
}
JSON 格式的大数组
[{"group_id":87,"group_name":"\u06af\u0632\u06cc\u0646\u0647 \u0647\u0627\u06cc \u0639\u0645\u0648\u0645\u06cc","group_slug":"%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":"","attributes":[{"attr_id":95,"attr_name":"\u062a\u0627\u0631\u06cc\u062e \u0627\u0646\u062a\u0634\u0627\u0631","attr_slug":"%d8%aa%d8%a7%d8%b1%db%8c%d8%ae-%d8%a7%d9%86%d8%aa%d8%b4%d8%a7%d8%b1","attr_desc":"","value":"144"},{"attr_id":96,"attr_name":"\u0648\u0636\u0639\u06cc\u062a \u0628\u0627\u0632\u0627\u0631","attr_slug":"stock","attr_desc":"","value":"instock"},{"attr_id":99,"attr_name":"\u0628\u0644\u0648\u062a\u0648\u062b","attr_slug":"%d8%a8%d9%84%d9%88%d8%aa%d9%88%d8%ab","attr_desc":"","value":"yes"},{"attr_id":100,"attr_name":"\u0648\u0627\u06cc \u0641\u0627\u06cc","attr_slug":"%d9%88%d8%a7%db%8c-%d9%81%d8%a7%db%8c","attr_desc":"","value":"no"}]},{"group_id":89,"group_name":"\u0635\u0641\u062d\u0647 \u0646\u0645\u0627\u06cc\u0634","group_slug":"%d8%b5%d9%81%d8%ad%d9%87-%d9%86%d9%85%d8%a7%db%8c%d8%b4","group_desc":"","attributes":[]},{"group_id":57,"group_name":"\u067e\u0631\u062f\u0627\u0632\u0646\u062f\u0647","group_slug":"%d9%be%d8%b1%d8%af%d8%a7%d8%b2%d9%86%d8%af%d9%87","group_desc":"","attributes":[]}]
最佳答案
我认为 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字符串),会更容易想出更好的想法,因为现在测试可能的解决方案并不容易
更新
首先,关于相关代码的几句话:
- 如果你计算“for”语句中的某些内容(我的意思是
sizeof($attributes)
),则循环会执行该命令 在每次迭代中 return $attributes[$i];
如果所有 IF/ELSE 语句失败,将仅返回 $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;
}
关于php - 如何通过 array_filter 返回子数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40870536/