为了账号安全,请及时绑定邮箱和手机立即绑定

使用 PHP 搜索非对称多维数组

使用 PHP 搜索非对称多维数组

PHP
慕斯王 2023-09-15 10:31:16
为了使用 PHP 搜索数组,我发现了很多问题和一些很好的答案。但每次,脚本对问题的回答都过于完美,而不是全局的或所有数组都是对称的。我的数组看起来像这样:$data = [    'steve' => [        'id'     => [            '#text' => 1,        ],        'pseudo' => [            '#text' => 'LOL'        ],    ],    'albert' => [        'id'     => [            '#text' => 2,        ],        'pseudo' => [            '#text' => 'KILLER'        ],    ],    'john' => [        'id'     => [            '#text' => 3,        ],        'pseudo' => [            '#text' => 'NOOBS'        ],    ],];这意味着我的数组可以看起来漂亮地对称生成,或者完全混乱并具有随机子数组。我的目标是内部搜索并找到 AN ID 的伪值。不幸的是,我无法更改给我这个结果的网络服务。我曾尝试使用 array_column 或 array_search,但我成功返回的唯一结果是它是否找到了某些内容。但无法识别。而且我的脚本非常慢。就像是 :search($array, 2); //which return KILLER或者也许更有选择?我的数组可以有很多 ID(100+)。所以我试图找到一些优化的东西。:/
查看完整描述

2 回答

?
BIG阳

TA贡献1859条经验 获得超6个赞

可能有一百万种方法可以做到这一点,但最终您将需要一些能够过滤值和该值的路径的递归方法。为此,以下是这百万种方法中的一种。

它使用预定义的迭代器:

  • 回调过滤器迭代器

  • 递归迭代器迭代器

  • 递归数组迭代器

与自定义PathAsKeyDecorator迭代器结合使用。

演示在这里

<?php

declare(strict_types=1);


final class PathAsKeyDecorator implements \Iterator

{

    private RecursiveIteratorIterator $inner;


    public function __construct(RecursiveIteratorIterator $inner)

    {

        $this->inner = $inner;

    }


    public function current()

    {

        return $this->inner->current();

    }


    public function next(): void

    {

        $this->inner->next();

    }


    public function key()

    {

        $path = [];

        for ($i = 0, $depth = $this->inner->getDepth(); $i <= $depth; $i++) {

            $path[] = $this->inner->getSubIterator($i)->key();

        }


        return $path;

    }


    public function valid(): bool

    {

        return $this->inner->valid();

    }


    public function rewind(): void

    {

        $this->inner->rewind();

    }

}


$input = [

    'steve'  => [

        'id' => [

            '#text' => 1,

        ],

    ],

    'albert' => [

        'id' => [

            '#text' => 2,

        ],

    ],

    'john'   => [

        'profil' => [

            'id' => [

                '#text' => 3,

            ],

        ],

    ],

];


// this is the filter function that should be customized given your requirements

// or create a factory function which produces these types of filter functions

$filter = static function ($current, array $path): bool {

    // with help from the PathAsKeyDecorator

    // we can decide on the path to the current value

    return ['id', '#text'] === array_slice($path, -2)

        // and the current value

        && 2 === $current;

};



// configure the iterator

$it = new CallbackFilterIterator(

    new PathAsKeyDecorator(new RecursiveIteratorIterator(new RecursiveArrayIterator($input))),

    $filter,

);


// traverse the iterator

foreach ($it as $path => $val) {

    print_r([

        'path' => $path,

        'val'  => $val

    ]);

}


查看完整回答
反对 回复 2023-09-15
?
扬帆大鱼

TA贡献1799条经验 获得超9个赞

完整编辑阵列结构变化的原因。json_encode 用于将数组更改为字符串。仅当每个数组切片中有一个 id 和一个伪值时,它才起作用。


$data = [

    'steve' => [

        'id'     => [

            '#text' => 1,

        ],

        'pseudo' => [

            '#text' => 'LOL'

        ],

    ],

    'albert' => [

        'id'     => [

            '#text' => 2,

        ],

        'pseudo' => [

            '#text' => 'KILLER'

        ],

    ],

    'john' => [

        'id'     => [

            '#text' => 3,

        ],

        'pseudo' => [

            '#text' => 'NOOBS'

        ],

    ],

];



$data = json_encode($data, JSON_NUMERIC_CHECK);

preg_match_all('~"id":{"#text":([^{]*)}~i', $data, $ids);

preg_match_all('~"pseudo":{"#text":"([^{]*)"}~i', $data, $pseudos);


$lnCounter = 0;

$laResult  = array();

foreach($ids[1] as $lnId) {

    $laResult[$lnId] = $pseudos[1][$lnCounter];

    $lnCounter++;

}


echo $laResult[2];


查看完整回答
反对 回复 2023-09-15
  • 2 回答
  • 0 关注
  • 85 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信