-2

I have this array:

array{
  0 => string '1' (length=1) 
  1 => string '18' (length=2)
  2 => string '18' (length=2)
  3 => string '1' (length=1)
  4 => string '1' (length=1)
  5 => string '1' (length=1)
  6 => string '1' (length=1)
  7 => string '1' (length=1)
  8 => string '18' (length=2)
  9 => string '18' (length=2)
}

I want to make it looks like this:

array{
  0 => array (
          0 => '1'
             )
  1 => array (
          0 => '18' 
          1 => '18' 
             )
  2 => array (
          0 => '1'
          1 => '1'
          2 => '1'
          3 => '1'
          4 => '1'
          5 => '1' 
             )
  3 => array (
          0 => '18'
          1 => '18' 
             )
}

So the idea is, i want to group the array by finding if the next array key is the same as the current key, if the next array key is the same as the current one, it merges it inside a new array, like grouping.

i couldn't really find an answer here, or on google, the idea is there is key 1 then 2 the 1 again, i want to group the similar keys until a different key comes in, the key (2) broke the grouping and started a new group, then broke by key 1 to start a new group as well,

the idea is for chatting messages, facebook and msn they group the messages by the user who sent them, untill another user comes in and break the group. but can't find out how.

Thanks

3
  • i tried using Next n prev n curr, that if next(array)->sender == curr(array)->sender... but couldn't think logicaly after this step. $ress = array(); for ($i = 0; $i<count($results); $i++){ if($results[$i]->sender == @$results[$i-1]->sender){ $ress[$i][] = $results[$i]->sender; $ress[$i][] = $results[$i-1]->sender; }else{ $ress[$i] = $results[$i]->sender; } } var_dump($ress); that's the for i test i did.
    – Emad Ha
    Commented Aug 14, 2012 at 18:50
  • Think facebook chat and msn, they group message by the sender, until another sender appears, it breaks the group.
    – Emad Ha
    Commented Aug 14, 2012 at 18:52
  • okay i updated the array example, please note there's an extra array, ignore that i needed to show this to @nickb
    – Emad Ha
    Commented Aug 14, 2012 at 19:36

2 Answers 2

0

You'll have to loop it yourself, finding the blocks where the current element $i matches the next element $j, continuing to increment $j while the equality holds, and then slicing that section off into its own array with array_slice():

$new = array(); $count = count( $old) - 1;
for( $i = 0, $j = 1; $i < $count; $i = $j, $j = $i + 1) {
    while( $old[$i] === $old[$j]) $j++;
    $new[] = array_slice( $old, $i, $j - $i);
}

This will print:

Array
(
    [0] => Array
        (
            [0] => 1
        )

    [1] => Array
        (
            [0] => 18
            [1] => 18
        )

    [2] => Array
        (
            [0] => 1
            [1] => 1
            [2] => 1
            [3] => 1
            [4] => 1
        )

    [3] => Array
        (
            [0] => 18
            [1] => 18
        )

)
6
  • this is giving me an endless loop, if i put it like : $new = array(); $count = count( $results) - 1; for( $i = 0, $j = 1; $i < $count; $i = $j, $j = $i + 1) { while( $results[$i] === $results[$j]) $j++; $new[] = array_slice( $results, $i, $j - $i); }
    – Emad Ha
    Commented Aug 14, 2012 at 19:12
  • the returned data from the database are stored in $results
    – Emad Ha
    Commented Aug 14, 2012 at 19:14
  • @Emad - It works in my test, as you can see above. Renaming the array to $results and copy/pasting the code from your comment, it still works.
    – nickb
    Commented Aug 14, 2012 at 19:20
  • okay, fixed the array keys in my code. now works, but not grouping at all, how can i style post a styled array here, if i copy/paste it here it looks crappy.
    – Emad Ha
    Commented Aug 14, 2012 at 19:33
  • i upadeted the question, now it has the output after your suggestion, the original result has doesnt have a child array.
    – Emad Ha
    Commented Aug 14, 2012 at 19:37
0

untested because you didn't provide copy/paste sample input.

$prev = current($arr);
$grp = array();
$res = array();
foreach ($arr as $v) {
    if ($v === $prev) {
        $grp[] = $v;
    } else {
        $res[] = $grp;
        $grp = array();
    }
    $prev = $v;
}
3
  • @Emad you'll get better replies if you show the output of echo var_export($your_array); which can be copy/pasted.
    – Cups
    Commented Aug 14, 2012 at 18:55
  • the array is too big, it worked somehow, but still adding extra uneeded keys.
    – Emad Ha
    Commented Aug 14, 2012 at 19:17
  • but again, think facebook chat, lets say they have array of the messages items, for sure they have inside each array an element which refers to the sender(sender_id=xxx), so they probably regroup the messages, by the sender untill the next array key has a different sender, it breaks the grouping, and open a new group...etc
    – Emad Ha
    Commented Aug 14, 2012 at 19:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.