2016-11-29 14 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_id или attr_name или attr_slug, поэтому i создал эту функцию, которая использует 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

 Смежные вопросы

  • Нет связанных вопросов^_^