2010-09-30 4 views
7

estoy tratando de conseguir algo como esto de trabajo:¿Cómo uso un iterador de matriz recursivo para procesar una matriz multidimensional?

function posts_formatter (&$posts){ 
    foreach ($posts as $k => $v){ 

     if (is_array($v)){ 

      posts_formatter($v); 

     }else{ 

      switch (strtolower($k)){ 

       # make email addresses lowercase 
       case (strpos($k, 'email') !== FALSE): 
        $posts[$k] = strtolower($v); 
        break; 

       # make postcodes uppercase 
       case (strpos($k, 'postcode') !== FALSE): 
        $posts[$k] = strtoupper($v); 
        break; 

       # capitalize certain things 
       case (strpos($k, 'line1') !== FALSE): 
       case (strpos($k, 'line2') !== FALSE): 
       case (strpos($k, 'line3') !== FALSE): 
       case (strpos($k, 'forename') !== FALSE): 
       case (strpos($k, 'surname') !== FALSE): 
        $posts[$k] = capitalize($v); 
        break; 
      } 

     } 
    } 
} 

Se irá correctamente a través de la matriz y dar formato a los valores, pero no puedo conseguirlo para volver ellos. He jugado con eliminar el & de la declaración de función y agregar una devolución al final, pero no hará nada.

Además, estoy pensando que quizás usar un RecursiveArrayIterator podría ser el camino a seguir. Sin embargo, a pesar de la presencia de un libro justo frente a mí con un capítulo sobre los iteradores de SPL, sus ejemplos son inútiles para poder lograr lo que intento. ¿Cómo voy a implementar uno?

Editar:

array (
    'user' => 
    array (
    'title' => 'Mr.', 
    'forename' => 'lowercase', 
    'surname' => 'name', 
    'businessName' => 'some dude', 
    'telephone' => '07545464646', 
    'postcode' => 'wa1 6nj', 
    'line1' => 'blergh road', 
    'line2' => 'randomLY cApitaLIzed wOrds', 
    'line3' => '', 
), 
    'email' => '[email protected]', 
    'address' => 
    array (
    'postcode' => 'ab1 1ba', 
    'line1' => 'test road', 
    'line2' => 'testville', 
    'line3' => 'testshire', 
), 
    'date' => '2010-09-30' 
) 
+0

cuidado para proporcionar un array 'ejemplo var_export' ? – Gordon

+0

Bueno, la matriz puede ser cualquier matriz multidimensional (o básica), que es el punto completo. Todo lo que la función necesita hacer es buscar esas claves específicas, que pueden existir o no dentro de la matriz y formatear sus valores. La pregunta es conseguir que los devuelva al guión. – bcmcfc

+0

Pregunto porque para escribir un ejemplo, me gustaría utilizar sus datos reales en lugar de crear una matriz ficticia. Es solo para que sea menos tedioso programar las cosas por ti. – Gordon

Respuesta

18

autorización, aquí es un algo rápido para que usted pueda averiguar:

$data = array(
    'title' => 'how to work with iterators', 
    'posts' => array(
     array(
     'title' => 'introduction to iterators', 
     'email' => '[email protected]' 
    ), array(
     'title' => 'extending iterators', 
     'email' => '[email protected]' 
    ) 
)); 

La idea principal es influir en cómo el Iterator devuelve el elemento current. Los Iteradores son apilables, por lo que debe usar un RecursiveArrayIterator y envolverlo en un RecursiveIteratorIterator. Para lograr una funcionalidad personalizada, puede subclase el RecursiveIteratorIterator (como se muestra a continuación) o utilizar iteradores adicionales para decorar el RecursiveIteratorIterator:

class PostFormatter extends RecursiveIteratorIterator 
{ 
    public function current() 
    { 
     $current = parent::current(); 
     switch($this->key()) { 
      case 'email': 
       $current = strtolower($current); 
       break; 
      case 'title': 
       $current = ucwords($current); 
       break; 
      default: 
       break; 
     } 
     return $current; 
    } 
} 

Entonces sólo tiene que foreach sobre el iterador

$it = new PostFormatter(new RecursiveArrayIterator($data)); 
foreach($it as $key => $post) { 
    echo "$key: $post", PHP_EOL; 
} 

y obtener

title: How To Work With Iterators 
title: Introduction To Iterators 
email: [email protected] 
title: Extending Iterators 
email: [email protected] 

Puede intentar recuperar la matriz desde las funciones iterator_to_array o iterator_apply. Sin embargo, para obtener los valores vuelve a aplicar la estructura matriz original, usted no necesita un iterador:

array_walk_recursive($data, function(&$val, $key) { 
    switch($key) { 
     case 'title': $val = ucwords($val); break; 
     case 'email': $val = strtolower($val); break; 
     default: break; 
    } 
}); 
print_r($data); 

Nota: cambio de Lambda con el nombre de función al usar PHP 5.3 <

+0

Gracias por su ayuda Gordon. Solo una Q más rápida: ¿cómo la modifico para devolver la matriz procesada con la estructura original intacta? – bcmcfc

+0

@bcmcfc ver la actualización por favor – Gordon

+0

Gracias por la explicación detallada. – bcmcfc

Cuestiones relacionadas