JLT
JLT

Reputation: 83

how to filter array where a key's value matches in php

I'm not sure how to do this, but I would like to filter one set of data results while iterating through another. What is the correct way to do this? I am trying array_filter but I'm not sure I grasp how to make this work similar to a sql where statement: edit: These below queries are to a MySQL database

    $arr_years = $wpdb->get_results("SELECT id, submodel_id, year FROM `subyears` ORDER by submodel_id", ARRAY_A);
    $arr_submodels = $wpdb->get_results("SELECT id, model_id, sub_name FROM `submodels` ORDER by model_id", ARRAY_A);
    foreach($arr_submodels as $submodel){
        $filtered = array_filter($arr_years, function ($value,$key){
            return $value == $submodel->id && $key == 'year';
        });
    //do something with $filtered here
    }

Basically I want the equivalent of "where submodel_id == id of the other array". I think array_map might do what I want but I don't grasp that either, but if that is a better way please let me know and show me how? Thanks.

Edit: added example output snippets of array's: $arr_years:

array(50) { [0]=> array(3) { ["id"]=> string(1) "1" ["submodel_id"]=> string(1) "2" ["year"]=> string(4) "2020" } [1]=> array(3) { ["id"]=> string(1) "2" ["submodel_id"]=> string(1) "3" ["year"]=> string(4) "2020" } [2]=> array(3) { ["id"]=> string(1) "3" ["submodel_id"]=> string(1) "4" ["year"]=> string(4) "2020" } [3]=> array(3) { ["id"]=> string(1) "4" ["submodel_id"]=> string(1) "5" ["year"]=> string(4) "2020" } [4]=> array(3) { ["id"]=> string(1) "5" ["submodel_id"]=> string(1) "6" ["year"]=> string(4) "2020" } }

$arr_submodels:

array(50) { [0]=> array(3) { ["id"]=> string(1) "2" ["model_id"]=> string(2) "22" ["sub_name"]=> string(13) "RMK KHAOS 155" } [1]=> array(3) { ["id"]=> string(1) "3" ["model_id"]=> string(2) "22" ["sub_name"]=> string(7) "RMK 144" } [2]=> array(3) { ["id"]=> string(1) "4" ["model_id"]=> string(2) "22" ["sub_name"]=> string(11) "PRO-RMK 155" } [3]=> array(3) { ["id"]=> string(1) "5" ["model_id"]=> string(2) "22" ["sub_name"]=> string(11) "PRO-RMK 163" } [4]=> array(3) { ["id"]=> string(1) "6" ["model_id"]=> string(2) "22" ["sub_name"]=> string(11) "PRO-RMK 174" } [5]=> array(3) { ["id"]=> string(1) "7" ["model_id"]=> string(2) "23" ["sub_name"]=> string(7) "SKS 146" } }

The reason I don't do this in the sql is I need to create a comma delimited list of years from the years table for each submodel id...it's a many to one relationship.

Thanks

Upvotes: 0

Views: 1036

Answers (1)

kainaw
kainaw

Reputation: 4334

Based on new information, this is what you likely want:

$arr = $wpdb->get_results("
  SELECT GROUP_CONCAT(sy.year) as years,
  sm.model_id as model_id,
  sm.sub_name as sub_name
  FROM `subyears` sy
  JOIN `submodels` sm
  ON sy.submodel_id=sm.id
  GROUP BY sm.model_id
  ORDER BY sm.model_id
");

The "years" column in the returned array will contain all of the years. By default, they are comma separated.

---OLD ANSWER BELOW---

You should do this in the query itself:

$arr = $wpdb->get_results("
  SELECT sy.id, sy.year, sm.id, sm.model_id, sm.sub_name
  FROM `subyears` sy
  JOIN `submodels` sm
  ON sy.submodel_id=sm.id
  ORDER BY sm.model_id
");

If you really insist on doing it outside the query, you need to create an entirely new array:

$arr = array();
foreach($arr_years as $year)
  foreach($arr_submodels as $submodel)
    if($year->submodel_id == $submodel->id)
      $arr[] = (object) array_merge((array) $year, (array) $submodel));

Now, $arr contains all the objects from the two arrays merged together where submodel_id == id. You can loop through $arr and do what you want.

I used array_merge because I don't know of any function to merge objects. If there is one, it will be more efficient.

Upvotes: 1

Related Questions