Pregunta

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.

¿Fue útil?

Solución

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

Otros consejos

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;
            },
            []
        )
    )
);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top