Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP]Recursive iterator nie zwraca zmienionych danych
viking
post 16.09.2019, 08:15:00
Post #1





Grupa: Zarejestrowani
Postów: 5 370
Pomógł: 909
Dołączył: 30.08.2006

Ostrzeżenie: (0%)
-----


Taki kod: http://sandbox.onlinephpfunctions.com/code...ce7f2ac1c9d91f5

Ktoś wie może czemu po zmianie tablicy finalnie nie jest ona zwracana? Jeśli zaraz po offsetSet dać offsetGet wartość jest poprawna.


--------------------
Go to the top of the page
+Quote Post
Neutral
post 17.09.2019, 13:53:36
Post #2





Grupa: Zarejestrowani
Postów: 252
Pomógł: 38
Dołączył: 10.01.2016

Ostrzeżenie: (0%)
-----


Dostałem odpowiedź na IRCu (FREENODE) kanał ##PHP.

Cytat
+Bittarman: I'd use a recursive array_map
Ja: Yes, but I want on method offsetSet().

+Bittarman: you cannot just make a method do something that it doesn't do.
+Bittarman: using offsetSet you'd only set the outermost arrays offset

Ja: Bittarman; where is it in documentation?
+Bittarman: under arrayiterator

Ja: So that works, I must "need to instantiate ArrayObject and let it create ArrayIterator instances that refer to it either by using foreach or by calling its getIterator() method manually."?
+Bittarman: except you're using a recursiveiteratoriterator on it

Ja: Aha, OK. So I can't use recursiveiteratoriterator, that use offsetSet()?
+Bittarman: you can, but it will only work on the outermost layer.

+Bittarman: like I said, I'd just use a recursive array_map
Ja: In manual not have about "outermost layer", probably.


Ta metoda działa, tylko na najbardziej zewnętrznych indeksach, do tych środkowych "nie wchodzi" lub "nie chce ich modyfikować". Żeby napisać, to co chcesz powinieneś skorzystać z rekursywnej funkcji array_map tak jak podpowiedział mi użytkownik na IRCu.

Cytat
This iterator allows to unset and modify values and keys while iterating over Arrays and Objects.

When you want to iterate over the same array multiple times you need to instantiate ArrayObject and let it create ArrayIterator instances that refer to it either by using foreach or by calling its getIterator() method manually.


Źródło

Kod użytkownika +Bittarman z IRCa z wykorzystaniem map*.

Kod
<?php

$array = [
        'one' => 'One',
        'two' => 'Two',
        'three' => [
            'four' => 'Four',
            'items' => [
                'six' => 'Six',
                'seven' => 'Seven'
            ]
        ],
    ];

function clean($in, $key) {
    if ($key === 'items') {
        return [];
    }
    if (is_array($in)) {
        return array_map('clean', $in, array_keys($in));
    }
    return $in;
}
$out = array_map('clean', $array, array_keys($array));
var_dump($out);



W przeciwnym razie chyba musisz, ale nie jestem pewien napisać coś w tym stylu.

Musisz chyba ustawić korzeń (root) array na inną pozycję level zagnieżdżenia i wtedy można modyfikować te drzewo arraya.

A tutaj mój kod, wpierałem się komentarzem w manualu PHP - źródło.

Kod
<?php
///ini_set('error_reporting', E_ALL);
$array = [
        'one' => 'One',
        'two' => 'Two',
        'three' => [
            'four' => 'Four',
            'items' => [
                'six' => 'Six',
                'seven' => 'Seven'
            ]
        ],
    ];

$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array), RecursiveIteratorIterator::SELF_FIRST);
  
foreach($iterator as $key => $value) {
  
    $currentDepth = $iterator->getDepth();
    for($subDepth = $currentDepth; $subDepth >= 0; $subDepth--) {
      if( $key == 'items') {
        
         $value = [];
      }
  
      $subIterator = $iterator->getSubIterator($subDepth);

      $subIterator->offsetSet($subIterator->key(), ($subDepth === $currentDepth ? $value : $iterator->getSubIterator(($subDepth+1))->getArrayCopy()));
    }


}

var_dump($iterator->getArrayCopy());

?>


Za napisanie kodu szczególnie podziękowania dla +Bittarman z kanału ##PHP oraz daniel1302 z kanału #4programmers oba na FREENODE.

Ten post edytował Neutral 17.09.2019, 17:17:11
Go to the top of the page
+Quote Post
viking
post 18.09.2019, 07:18:18
Post #3





Grupa: Zarejestrowani
Postów: 5 370
Pomógł: 909
Dołączył: 30.08.2006

Ostrzeżenie: (0%)
-----


Dzięki wielkie za fatygę i wkład. Muszę jeszcze potestować jaką mają wydajność iteratory vs funkcje rekurencyjne na dużej tablicy bo podobno słabo z tym w pierwszym przypadku.


--------------------
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 21.10.2019 - 06:29