2016-11-29 67 views
2

我想创建一个大的阵列中进行搜索,并返回某些字段函数返回一个子阵列,该阵列用于例如像这样(var_dump的大阵):如何通过array_filter

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_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":[]}] 

回答

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字符串),它会更容易想出更好的主意,因为现在它是不容易

首先测试可能的解决方案

UPDATE关于在问题中发布的代码的几句话:

  1. 如果您在'for'语句(我的意思是sizeof($attributes))中计数了某些内容,循环doe s表示命令上 每次迭代
  2. return $attributes[$i];将简单地返回,如果所有的if/else语句失败

所以我固定这些点与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; 
} 
+0

谢谢您的回答,但有没有更合适的如果你给我一个线索,我会很感激。 – Amin

+1

@ Amiut7我已经更新了答案 –

+0

非常感谢,它的作品令人惊叹:) – Amin