logo

Jak vyhledat objekt v hodně komplexním objektu s variabilní hloubkou vnoření

01.08.2019 19:10
1
Tak jsem tu narazil na jednu jobovku, nad kterou moje mozkové závity se začínají přehřívat a nenašel jsem na to žádné elegantní řešení.

Problém je takový, že mám hodně komplexní objekt a potřebuji v něm najít podobjekt s hodnotou.

Vypadá to asi tak nějak (uvádím jen začátek objektu a značně jsem to zjednodušil)
PHP kód:
stdClass Object
        
(
            [
0] => stdClass Object
                
(
                    [
1] => stdClass Object
                        
(
                            [
2] => 
                            [
3] => Array
                                (
                                )

                        )

                    [
4] => stdClass Object
                        
(
                        )

                    [
5] => stdClass Object
                        
(
                            [
6] => stdClass Object
                                
(
                                    [
7] => 
                                    [
8] => 
                                    [
9] => Array
                                        (
                                        )

                                    [
10] => Array
                                        (
                                                  [
0] => stdClass Object
                                                        
(
                                                            [
12] => 12345
                                                            
[13] => Alfa
                                                        
)

                                                    [
1] => stdClass Object
                                                        
(
                                                            [
12] => 67890
                                                            
[13] => Beta
                                                        
)
                                        )

                                    [
11] => Array
                                        (
                                        ) 
Jde o to, že potřebuji dostal pole, ve kterém se nachází ty 2 objekty, tj. objekt, který mý vlastnost "Alfa" a objekt, který má vlastnost "Beta", abych si toto pole objektů mohl projít foreachem.

Problém je, že objekt je extrémně složitý a je náhodně nakombinovaný z objektů a polí, indexy mají také náhodné řazení a náhodná je i úroveň vnoření, tj. někdy to pole objektů může být v první vrstvě, někdy v páté, atd..

Jediné, čeho se můžu chytit, tak je to číslo 12345, to vím dopředu, že tam je, a je tam pouze 1x tj. musím udělat funkci, která mi rekurentně projde objekt, najde mi hodnotu 12345 v podobjektu a jakmile ji najde, vrátí mi rodičovské pole, ve kterém se nachází. Ale vůbec netuším jak, uvítám každou radu.

Co se právě děje na Webtrhu?

01.08.2019 19:20
2
Tipuji, že používáš PHP 5.5 a výše. Nepomohlo by klasické array_search?
01.08.2019 19:39
3
Původně odeslal michal731
Tipuji, že používáš PHP 5.5 a výše. Nepomohlo by klasické array_search?
PHP 7.3 , nevím, jak by mi to array_search takhle celý prošel a ještě k tomu mix objektů a polí, napiš kód, jak to myslíš :)
01.08.2019 19:44
4
Bude to o testování a kombinování ale myslím, že by to mohlo jít. Dá se na to najít více způsobů.
php search in multiple array

Sorry, nejsem u pc tak teď nic nenapíši :)
01.08.2019 19:48
5
Původně odeslal Engineer
PHP 7.3 , nevím, jak by mi to array_search takhle celý prošel a ještě k tomu mix objektů a polí, napiš kód, jak to myslíš :)
Nemyslím, že přímo array_search, ale v komentech na manuálové stránce k této funkci je mrtě pokusů o rekurzi. Předpokládám, že půjdou rozšířit o test na objekt.
01.08.2019 21:08
6
Kód:
<?php

$data = [
    (object)[
        (object)[
            [null, 1, [
                'sss'
            ],
                [
                    (object)['x', 'bb'],
                    (object)['c', 'aa']
                ]
            ]
        ]
    ],

    (object)[
        (object)[
            [null, 1, [
                'sss'
            ],
                [
                    ['x', 'bzb'],
                    ['c', 'aaa']
                ]
            ]
        ]
    ]
];

function test($data, $najdi)
{
    foreach ($data as $k => $v) {
        if ((is_array($v) && in_array($najdi, $v) ||
            is_object($v)&& in_array($najdi, (array)$v))) {
            print_r($data);
        }
        if (is_array($v) || is_object($v)) {
            test($v, $najdi);
        }
    }
}

test($data, 'aa');
vypise:

Kód:
Array
(
    [0] => stdClass Object
        (
            [0] => x
            [1] => bb
        )

    [1] => stdClass Object
        (
            [0] => c
            [1] => aa
        )

)
02.08.2019 02:14
7
Proč je ten objekt tak ošklivý? Odkud pochází? Dá se jeho struktura upravit?
Hledaný řetězec je tam pouze jednou? Může existovat i jako součást delšího řetězce?
Nachází se v tom objektu kromě stdClass jiné než skalární hodnoty (string, int, bool...)?
02.08.2019 06:34
8
Jak píše qye - můžeš to projít rekurzivní funkcí a když narazíš na to co hledáš, tak si to uložit.