如何使用递归数组迭代器来处理多维数组?

发布于 2024-09-25 09:00:47 字数 1961 浏览 3 评论 0原文

我试图让这样的东西工作:

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

        }
    }
}

它将正确地遍历数组并格式化值,但我无法让它返回它们。我尝试过从函数声明中删除 & 并在末尾添加 return,但它不会执行任何操作。

此外,我想也许使用 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'
)

I'm trying to get something like this working:

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

        }
    }
}

It will correctly go through the array and format the values but I can't get it to return them. I've played around with removing the & from the function declaration and adding a return at the end but it won't do anything.

Additionally, I'm thinking perhaps using a RecursiveArrayIterator might be the way to go. However, despite the presence of a book right in front of me with a chapter on SPL Iterators its examples are useless towards being able to achieve what I'm trying to. How would I go about implementing one?

Edit:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

世态炎凉 2024-10-02 09:00:47

好的,这里有一个供您快速了解的内容:

$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

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通过迭代器

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

并 get

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 时将 Lambda 与函数名称交换

Ok, here is a quick something for you to figure out:

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

The main idea is to influence how the Iterator returns the current element. Iterators are stackable, so you should use a RecursiveArrayIterator and wrap it into a RecursiveIteratorIterator. To achieve custom functionality, you can either subclass the RecursiveIteratorIterator (as shown below) or use additional iterators to decorate the 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;
    }
}

Then you simply foreach over the iterator

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

and get

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

You can try to get the array back from the with iterator_to_array or iterator_apply functions. However, to get the values reapplied to the original array structure, you dont need an iterator:

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

Note: exchange Lambda with Function name when using PHP<5.3

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文