Estoy refactorizando un código a programación funcional para mejorar la legibilidad y encuentro un problema con una matriz. Quiero cambiar una matriz de objetos a una matriz simple con matrices de valores.

La primera matriz se ve así:

array(2) {
  [5701]=>
  object(stdClass)#123 (3) {
    ["id"]=>
    string(4) "5701"
    ["username"]=>
    string(6) "s67688"
    ["state"]=>
    string(6) "Inactive"    
  }
  [5762]=>
  object(stdClass)#136 (3) {
    ["id"]=>
    string(4) "5762"
    ["username"]=>
    string(6) "s67701"
    ["state"]=>
    string(6) "Active"
  }  
}

Quiero convertirlo en algo como esto:

array(2) {
  [0]=>
  array(3) {
    [0]=>
    id(4) 5701
    [1]=>
    string(6) "s67688"
    [2]=>
    string(8) "Inactive"    
  }
  [1]=>
  array(3) {
    [0]=>
    int(4) 5762
    [1]=>
    string(6) "s67701"
    [2]=>
    string(8) "Active"    
  }
}

Con un foreach simple es fácil de lograr, pero cuando intento el siguiente código:

$newArr = array_map(function($value){
               return array_values(get_object_vars($value));
          }, $baseArr);

El resultado es el siguiente:

array(2) {
  [5701]=>
  array(3) {
    [0]=>
    id(4) 5701
    [1]=>
    string(6) "s67688"
    [2]=>
    string(8) "Inactive"    
  }
  [5762]=>
  array(3) {
    [0]=>
    int(4) 5762
    [1]=>
    string(6) "s67701"
    [2]=>
    string(8) "Active"    
  }
}

Como puede ver, las claves de la matriz base no cambian, ¿por qué sucede esto?

Este es el foreach original que devuelve lo que quiero:

$newArr = [];
foreach ($baseArr as $value) {
     $newArr[] = array_values(get_object_vars($user));
}

También probé array_walk.

1
iRynoh 20 feb. 2018 a las 22:46

2 respuestas

La mejor respuesta

array_map aplica una devolución de llamada a los valores y no modifica las claves. También simplifiqué la obtención de los valores simplemente enviando a array:

$newArr = array_values(array_map(function($v){
                                     return array_values((array)$v);
                                 }, $baseArr));

Puede usar el array_values después como arriba o antes:

$newArr = array_map(function($v){
                        return array_values((array)$v);
                    }, array_values($baseArr));

Personalmente lo mantendría como una matriz asociativa:

$newArr = array_values(array_map(function($v){ return (array)$v; }, $baseArr));
2
AbraCadaver 20 feb. 2018 a las 20:03

Si puede utilizar una biblioteca, puede hacerlo fácilmente con Tarsana Functional

use Tarsana\Functional as F;
$newArr = F\value(F\map(F\values(), $baseArr));

Nota soy el autor de esa biblioteca.

1
webNeat 24 jul. 2018 a las 19:35