XTRUST.ORG
XTRUST.ORG

Reputation: 3392

Split flat array into grouped subarrays containing values from consecutive key in the input array

I have an array from array_diff function and it looks like below:

Array
(
    [0] => world
    [1] => is
    [2] => a
    [3] => wonderfull
    [5] => in
    [6] => our
)

As you can see, we have a gap between the keys #3 and #5 (i.e. there is no key #4). How can I split that array into 2 parts, or maybe more if there are more gaps? The expected output would be:

Array
    (
        [0] => Array
        (
           [0] => world
           [1] => is
           [2] => a
           [3] => wonderfull
        )
        [1] => Array 
        (
           [0] => in
           [1] => our
        ) 
    )

Upvotes: 4

Views: 224

Answers (3)

mickmackusa
mickmackusa

Reputation: 47894

This task is a perfect candidate for a reference variable. You unconditionally push values into a designated "bucket" -- in this case a subarray. You only conditionally change where that bucket is in the output array.

There are two important checks to make when determining if a new incremented key should be generated:

  1. if it is not the first iteration and
  2. the current key minus (the previous key + 1) does not equal 0.

Code: (Demo)

$nextKey = null;
$result = [];
foreach ($array as $key => $val) {
    if ($nextKey === null || $key !== $nextKey) {
        unset($ref);
        $result[] = &$ref;
    }
    $ref[] = $val;
    $nextKey = $key + 1;
}
var_export($result);

This solution generates an indexed array starting from zero with my sample input and uses only one if block. In contrast, AliveToDie's solution generates a numerically keyed array starting from 1 and uses two condition blocks containing redundant lines of code.

Upvotes: 0

Death-is-the-real-truth
Death-is-the-real-truth

Reputation: 72299

You can use old_key,new_key concept to check that there difference is 1 or not? if not then create new index inside you result array otherwise add the values on same index:-

<?php

$arr = Array(0 => 'world',1 => 'is',2 => 'a',3 => 'wonderfull',5 => 'in',6 => 'our');

$new_array = [];
$old_key = -1;
$i = 0;
foreach($arr as $key=>$val){
    if(($key-$old_key) ==1){
        $new_array[$i][] = $val;
        $old_key = $key;
    }
    if(($key-$old_key) >1){
         $i++;
         $new_array[$i][] = $val;
         $old_key = $key;
    }
}
print_r($new_array);

https://3v4l.org/Yl9rp

Upvotes: 5

Ricky Mo
Ricky Mo

Reputation: 7648

You can make use of the array internal pointer to traverse the array.

<?php
$arr = Array(0=>"world",1=>"is",2=>"a",3=>"wonderfull",5=>"in",6=>"our");
print_r($arr);

$result = Array();
$lastkey;
while($word = current($arr))
{
    $key = key($arr);
    if(isset($lastkey) && $key == $lastkey + 1)
    {
        $result[count($result) - 1][] = $word;
    }
    else
    {
        $result[] = Array($word);
    }
    $lastkey = $key;
    next($arr);
}
print_r($result);
?>

Upvotes: 1

Related Questions