如何通过array_filter

时间:2016-11-29 16:12:15

标签: 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部分中搜索特定属性并仅返回该属性,此搜索可以通过{{ 1}}或attr_idattr_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"
}

1 个答案:

答案 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字符串),那么更容易想出更好的想法,因为现在测试可能的解决方案并不容易

<强>更新

首先谈谈发布的问题代码:

  1. 如果你在'for'语句中计算一些内容(我的意思是sizeof($attributes)),循环就会执行该命令 每次迭代
  2. 如果所有IF / ELSE语句都失败,
  3. return $attributes[$i];将只返回$ attributes的最后一个元素
  4. 所以我修复了这些要点,并在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;
    }