Re-order multi-dimensional array so that rows with specific column value occur as every 4th row

Viewed 65

I am trying to rearrange my array according to "product_type". Every 4th position of index "product_type" should be "manufacturer" in the result.

If there are too few "seller" entries then the "manufacturer" entry may be exist in the next available position (and vice versa).

My current input is like this:

$arr1 = array(
    0 => ['product_type'=>'manufacturer','id'=>1], 
    1 => ['product_type'=>'manufacturer','id'=>2], 
    2 => ['product_type'=>'seller'], 
    3 => ['product_type'=>'seller'],
    4 => ['product_type'=>'seller'],
    5 => ['product_type'=>'seller'],
    6 => ['product_type'=>'seller'],
    7 => ['product_type'=>'manufacturer','id'=>3], 
);

My expected new array should be like this:

 Array(
    [0] => Array
        (
            [product_type] => seller
        )

    [1] => Array
        (
            [product_type] => seller
        )

    [2] => Array
        (
            [product_type] => seller
        )

    [3] => Array
        (
            [product_type] => manufacturer
            [id] => 1
        )

    [4] => Array
        (
            [product_type] => seller
        )

    [5] => Array
        (
            [product_type] => seller
        )

    [6] => Array
        (
            [product_type] => manufacturer
            [id] => 2
        )
    [7] => Array
        (
            [product_type] => manufacturer
            [id] => 3
        )

)

For this solution, I am trying this, but here in the result in 1st position I get "manufacturer" product.

$arr1 = array(
    0 => ['product_type'=>'manufacturer','id'=>1], 
    1 => ['product_type'=>'manufacturer','id'=>2], 
    2 => ['product_type'=>'seller'], 
    3 => ['product_type'=>'seller'],
    4 => ['product_type'=>'seller'],
    5 => ['product_type'=>'seller'],
    6 => ['product_type'=>'seller'],
    7 => ['product_type'=>'manufacturer','id'=>3], 
) ;


function rearrange(&$arr, $n) 
{ 
     for ($i = 0; $i < $n; $i++) 
     {  
        $j = $i+1;
        if($arr[$i]['product_type'] =='manufacturer'){
            if($j%4!= 0){
                //echo $i;
                $temp = $arr[$i];
                $arr[$i] = $arr[$i + 1]; 
                $arr[$i + 1] = $temp;
            } else {
                if ($i==0 || $i==1 || $i==2) {
                  $temp = $arr[$i];
                  $arr[$i] = $arr[$i + 1]; 
                  $arr[$i + 1] = $temp;
                } else {
                  $temp = $arr[$i];
                  $arr[$i] = $temp;
                }
                
            }
        } else {
          $temp = $arr[$i];
          $arr[$i] = $temp;
        }
     } 
  
   
    return $arr;
} 
$keys    = array_keys ($arr1);
$n = count ($keys);
$arr = rearrange($arr1, $n); 
print_r($arr);

FIDDLE

1 Answers
  • Store the manufacturer entries at every 4th key as you iterate.
  • Store the seller entries at every key that is not every 4th key.
  • Sort on the newly assigned keys.
  • Re-index the array.

This way your pattern is upheld as long as you have enough qualifying data to do so. When you have too much of one group of data, then it just gets lumped at the end.

Code: (Demo)

$arr1 = array(
    0 => ['product_type'=>'manufacturer','id'=>1], 
    1 => ['product_type'=>'manufacturer','id'=>2], 
    2 => ['product_type'=>'seller'], 
    3 => ['product_type'=>'seller'],
    4 => ['product_type'=>'seller'],
    5 => ['product_type'=>'seller'],
    6 => ['product_type'=>'seller'],
    7 => ['product_type'=>'manufacturer','id'=>3], 
);

$manuCounter = 0;
$sellerCounter = 0;
$result = [];
foreach ($arr1 as $row) {
    if ($row['product_type'] === 'manufacturer') {
        $manuCounter += 4;
        $result[$manuCounter] = $row;
    } else {
        ++$sellerCounter;
        if (!($sellerCounter % 4)) {
            ++$sellerCounter;
        }
        $result[$sellerCounter] = $row;
    }
}
ksort($result);
var_export(array_values($result));
Related