1

I have a multi-dimensional array like this:

Array
(
    [0] => Array
        (
            [id] => 1
            [email_id] => ok@gmail.com
            [password] => test
        )

    [1] => Array
        (
            [id] => 2
            [email_id] => check@gmail.com
            [password] => test
        )

    [2] => Array
        (
            [id] => 3
            [email_id] => an@gmail.com
            [password] => pass
        )

)

In the above array, password value is the same in two different rows. I need to merge the arrays which have duplicate values to get the following output:

Array
(
     [0] => Array
            (
               [0] => Array
                (
                    [id] => 1
                    [email_id] => ok@gmail.com
                    [password] => test
                )
        
            [1] => Array
                (
                    [id] => 2
                    [email_id] => check@gmail.com
                    [password] => test
                )
            ) 
    [1] => Array
        (
            [id] => 3
            [email_id] => an@gmail.com
            [password] => pass
        )

)

How to do this? I've tried array_merge() & foreach() loops, but I can't get this output.

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
DarkRose
  • 125
  • 4
  • 12
  • Are the duplicates determined only on the value for index `password` ? – Teena Thomas Jan 07 '13 at 18:49
  • For this, you will have to use your own merge function. This you can simply do using a foreach loop, that will determine if two arrays are duplicates, and if they are, make an array with the duplicate – kokx Jan 07 '13 at 18:52
  • i dnt have two different arrays to merge...single array with multiple key values – DarkRose Jan 07 '13 at 19:06

2 Answers2

2

Try,

$arr = array( array('id'=>1, 'email_id'=>'ok@gmail.com', 'password'=>'test'),
  array('id'=>2, 'email_id'=>'check@gmail.com', 'password'=>'test'), 
  array('id'=>3, 'email_id'=>'an@gmail.com', 'password'=>'pass'));

  $new_arr = array();
  foreach($arr as $k => $v) {
      if( is_array($arr[$k+1]) && $arr[$k]['password'] === $arr[$k + 1]['password'] )
          $new_arr[] = array($arr[$k], $arr[$k+1]);
      else if( in_array_recursive($arr[$k]['password'], $new_arr) === FALSE ) 
              $new_arr[] = $v;
  }

  function in_array_recursive( $val, $arr) {
      foreach( $arr as $v ) {
          foreach($v as $m) {
              if( in_array($val, $m ) )
                  return TRUE;      
          }
      }
      return FALSE;
  }

  print_r($new_arr);

Demo

Teena Thomas
  • 5,139
  • 1
  • 13
  • 17
  • Despite the custom function's name, there is no "recursion" happening because the custom function is not calling itself. More accurately the custom function is making `in_array()` calls inside of a nested loop. – mickmackusa Aug 25 '21 at 05:20
-1

You only want to create more depth in your output array if there is more than one entry in the group. I personally wouldn't want that kind of variability in a data structure because the code that will print the data will need to go to extra trouble to handle associative rows of data that might be on different levels.

Anyhow, here's how I would do it with one loop...

Foreach Loop Code: (Demo)

$result = [];
foreach ($array as $row) {
    if (!isset($result[$row['password']])) {
        $result[$row['password']] = $row; // save shallow
    } else {
        if (isset($result[$row['password']]['id'])) {  // if not deep
            $result[$row['password']] = [$result[$row['password']]]; // make original deeper
        }
        $result[$row['password']][] = $row;  // save deep
    }
}
var_export(array_values($result));  // print without temporary keys

Functional Code: (Demo)

var_export(
    array_values(
        array_reduce(
            $array,
            function($result, $row) {
                if (!isset($result[$row['password']])) {
                    $result[$row['password']] = $row;
                } else {
                    if (isset($result[$row['password']]['id'])) {
                        $result[$row['password']] = [$result[$row['password']]];
                    }
                    $result[$row['password']][] = $row;
                }
                return $result;
            },
            []
        )
    )
);
mickmackusa
  • 43,625
  • 12
  • 83
  • 136