php - 如何通过 array_filter 返回子数组

标签 php arrays array-filter

我想创建一个在大数组中搜索并返回一些字段的函数,该数组例如是这样的(大数组的 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_idattr_nameattr_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字符串),会更容易想出更好的想法,因为现在测试可能的解决方案并不容易

更新

首先,关于相关代码的几句话:

  1. 如果你计算“for”语句中的某些内容(我的意思是sizeof($attributes)),则循环会执行该命令 在每次迭代中
  2. 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/

相关文章:

php - 加入几个 mp3 文件并使用 ffmpeg 输出为 mov 文件

c# - 如何将8个方向映射到一维数组

javascript - JS过滤数组内的数组

sorting - 如何仅对没有空白单元格的行进行排序?

javascript - 用一个数组过滤另一个数组

php - 密码盐存储

php - DirectoryIterator::getExtension() 版本

javascript - 从数据库获取图像并将其链接到 php 中的功能或新闻等

c - 将字符串数组分配和检索给 void 指针

java - 有没有更好的方法从 Java 中的 Enum 获取 String[] ?