在PHP中的多维数组中从数组中存储相同类型的值?

I have a multidimensional array in php like this:

 Array
 (
 [0] => Array
    (
        [Year_id] => 29
        [Make_id] => 7
        [Model_id] => 34
        [Engine_id] => 19
    )

[1] => Array
    (
        [Year_id] => 30
        [Make_id] => 7
        [Model_id] => 34
        [Engine_id] => 19
    )

[2] => Array
    (
        [Year_id] => 21
        [Make_id] => 7
        [Model_id] => 34
        [Engine_id] => 19
    )

[3] => Array
    (
        [Year_id] => 1
        [Make_id] => 7
        [Model_id] => 34
        [Engine_id] => 19
    )

[4] => Array
    (
        [Year_id] => 2
        [Make_id] => 7
        [Model_id] => 34
        [Engine_id] => 2
    )

[5] => Array
    (
        [Year_id] => 3
        [Make_id] => 7
        [Model_id] => 34
        [Engine_id] => 2
    )

[6] => Array
    (
        [Year_id] => 4
        [Make_id] => 7
        [Model_id] => 34
        [Engine_id] => 2
    )

 )

My code is as follows:

  <?php
      $cars = array
      (
      array("Year_id"=>29, "Make_id"=>7, "Model_id"=>34, "Engine_id"=>19),
      array("Year_id"=>30, "Make_id"=>7, "Model_id"=>34, "Engine_id"=>19),
      array("Year_id"=>21, "Make_id"=>7, "Model_id"=>34, "Engine_id"=>19),
      array("Year_id"=>1, "Make_id"=>7, "Model_id"=>34, "Engine_id"=>19),
      array("Year_id"=>2, "Make_id"=>7, "Model_id"=>34, "Engine_id"=>2),
      array("Year_id"=>3, "Make_id"=>7, "Model_id"=>34, "Engine_id"=>2),
      array("Year_id"=>4, "Make_id"=>7, "Model_id"=>34, "Engine_id"=>2)
      );
   echo '<pre>';
   print_r($cars);
   ?>

In above result, I have four ids named Year_id, Make_id, Model_id and Engine_id. Year_id may change any time but when any of remaining IDs change in value, I want to store those arrays in a separate array and again check for remaining arrays and when any of ID values change except Year_id, store those arrays in a separate array.

Right now it should store first four arrays in a separate array because Engine_id value changes. How to solve it? I am ready for bounty after 2 days.

$i = 0;
$sepr = 0;
$arr = array();
foreach($cars as $car) {
    $k = $i; $k = ($k > 0 ? $k-1 : 0);
    foreach($car as $key => $value) {
        if($key != "Year_id" && $value != $cars[$k][$key]) {
            $sepr++;
        }
    }
    $arr[$sepr][] = $car;
    $i++;
}

print_r($arr);

Here's how I would go about it. I will give you an approach which I think is decently efficient. You have the input array in this form :

 $cars = array
  (
  array("Year_id"=>29, "Make_id"=>7, "Model_id"=>34, "Engine_id"=>19),
  array("Year_id"=>30, "Make_id"=>7, "Model_id"=>34, "Engine_id"=>19),
  array("Year_id"=>21, "Make_id"=>7, "Model_id"=>34, "Engine_id"=>19),
  array("Year_id"=>1, "Make_id"=>7, "Model_id"=>34, "Engine_id"=>19),
  array("Year_id"=>2, "Make_id"=>7, "Model_id"=>34, "Engine_id"=>2),
  array("Year_id"=>3, "Make_id"=>7, "Model_id"=>34, "Engine_id"=>2),
  array("Year_id"=>4, "Make_id"=>7, "Model_id"=>34, "Engine_id"=>2)
  );

From what I understand, you don't care about the "Year_id" but if any of the other ids change, you want to separate those elements. Start by defining the output associative array, let's call it $output.

So you would do:

  $output = array();
  $key = $cars[0]["Make_id"].'-'.$cars[0]["Model_id"].'-'.$cars[0]["Engine_id"];
  $output[$key] = $cars[0];

Let me try to explain what I just did. I basically started indexing the output array in form of triples (containing information about 'Make_id','Model_id' and 'Engine_id') for every array in the $cars array. So you can imagine the indices/keys for the $ouput array would be something like this:

 $output{
     ["7-34-19"]=> array("Year_id"=>29, "Make_id"=>7, "Model_id"=>34, "Engine_id"=>19)
     ...
 }

I hope you get an idea of where I am headed and how do I plan to structure the output now. Now it's just a matter of going through every element of the $cars array, concatenating the three ids separated by hyphens ('-') in the format I show above and just looking up that key in the $output array. If it exists, simply push it to that spot or create a new element.

The code might me be along these lines (untested):

  //Just for the sake of clarity I start from 1 here as we have already taken care of the first element
  for($i = 1; $i < count($cars); $i++) {
      $key = $cars[i]["Make_id"].'-'.$cars[i]["Model_id"].'-'.$cars[i]["Engine_id"];
      if (array_key_exists($key,$output)){
        //That means we have found another car whose make_id, model_id and engine_id match
        //Simply push that array into the associative array like so:         
        array_push($output[$key],$cars[$i]);
     }

     else{
       //We have found a unique car as the key doesn't exist, simply add it to the array
       $output[$key] = $cars[$i];
     }
   }

So finally the $output array might look something like this:

 $output{
     ["7-34-19"]=> { 
         [0] => array("Year_id"=>29, "Make_id"=>7, "Model_id"=>34, "Engine_id"=>19),
         [1] => array("Year_id"=>30, "Make_id"=>7, "Model_id"=>34, "Engine_id"=>19),
         [2] => array("Year_id"=>21, "Make_id"=>7, "Model_id"=>34, "Engine_id"=>19),
         [3] => array("Year_id"=>1, "Make_id"=>7, "Model_id"=>34, "Engine_id"=>19)

         } 
     ["7-34-2"]=> {
         [0] => array("Year_id"=>2, "Make_id"=>7, "Model_id"=>34, "Engine_id"=>2),
         [1] => array("Year_id"=>3, "Make_id"=>7, "Model_id"=>34, "Engine_id"=>2),
         [2] => array("Year_id"=>4, "Make_id"=>7, "Model_id"=>34, "Engine_id"=>2)  

        }
 }

I understand the structure of the $output array is not very simplistic and it might vary depending on what you are ultimately wanting to achieve but it does the trick of segregating and combining the array elements based on the three keys in just a single for loop. So the algorithm is linear in time efficiency i.e. of O(N).

You obviously don't have to combine the keys with a hyphen, you could use any separator but the idea is to combine the three keys that matter in a unique way and make them the index of our output array which greatly improves the efficiency of this whole algorithm. Anyway, I hope I could clarify my thought process and get you started in the right direction.