2010-09-30 58 views
7

我想要得到这样的工作:如何使用递归数组迭代器来处理多维数组?

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; 
      } 

     } 
    } 
} 

它会正确地去通过阵列和格式化的值,但我不能让它归还。我已经玩过从函数声明中删除&,并在最后添加一个返回值,但它什么都不会做。

此外,我想或许使用RecursiveArrayIterator可能是要走的路。然而,尽管在我面前出现了一本关于SPL迭代器的章节,但它的例子对于我能够实现的目标是无用的。我将如何去实施一个?

编辑:

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

护理时交换LAMBDA提供'var_export'例如数组? – Gordon 2010-09-30 09:50:54

+0

那么,数组可以是任何多维(或基本)数组,这是整个点。所有函数需要做的就是查找那些可能存在也可能不存在于数组中并且格式化它们的值的特定键。问题是让它把它们输出回脚本。 – bcmcfc 2010-09-30 10:03:27

+0

我在问,因为为了写一个例子,我想使用你的实际数据,而不是拿出一个虚拟数组。这只是为了让你的代码不那么繁琐。 – Gordon 2010-09-30 10:06:41

回答

18

好吧,这里是一个快速的东西给你要弄清楚:

$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]' 
    ) 
)); 

主要思想是影响Iterator如何返回current元素。迭代器是可堆叠的,因此您应该使用RecursiveArrayIterator并将其包装到RecursiveIteratorIterator中。要实现自定义功能,你可以继承的RecursiveIteratorIterator(如下图所示),或使用额外的迭代器来装点RecursiveIteratorIterator:在迭代器

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

简单

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; 
    } 
} 

然后你foreach并获得

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

您可以尝试从iterator_to_arrayiterator_apply函数中获取数组。但是,要获得重新应用到原来的阵列结构中的值,你不需要一个迭代:

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); 

注:与功能名称中使用PHP < 5.3

+0

感谢您的帮助戈登。再简单一点Q-如何修改它,返回原始数组结构完整的已处理数组? – bcmcfc 2010-09-30 10:33:52

+0

@bcmcfc请参阅更新请致 – Gordon 2010-09-30 10:42:02

+0

感谢您的详细解释。 – bcmcfc 2010-09-30 10:48:41