• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed Return w pętli foreach, więcej, niżeli jeden raz.

Object Storage Arubacloud
0 głosów
348 wizyt
pytanie zadane 24 października 2016 w PHP przez HaKIM Szeryf (87,590 p.)
zamknięte 27 października 2016 przez HaKIM

Dzień dobry.

Przejdę do kodu, bo co tam będę dziabolił...

    public function getAmountUnits($nameArmy)
    {
        foreach ($this->units[0][$nameArmy] as $index => $unitObject) {
            return $unitObject->getAmount();
        }
    }

Jeżeli macie jakąś koncepcję nad jego(Lub całości) ulepszeniem, to nie krępować się. :D

Co niektórzy już dostrzegają błąd:

Return w foreach.

Jak poradzić sobie z tym stanem rzeczy?

Dostaję tylko pierwszy wynik, niezbyt fajnie.

Niby mogę zrobić to na print, acz...

Proces wywołania tej metody przebiega w taki sposób:

$army = new \WarCraft\Units\MakeUnits(new \WarCraft\Units\Units([
    'Army' => [
        new \WarCraft\Units\Unit\Ghost(3),
        new \WarCraft\Units\Unit\Orc(2)
    ]
]));

print $army->getAmountUnits('Army')."\n";

Klasa MakeUnits

/*Namespace*/

class MakeUnits
{
    /*...*/

    public function getAmountUnits($nameArmy)
    {
        return $this->units->getAmountUnits($nameArmy);
    }

    /*...*/
}

Klasa Units

 /*Namespace*/
class Units
{
    /*...*/

    public function getAmountUnits($nameArmy)
    {
        foreach ($this->units[0][$nameArmy] as $index => $unitObject) {
            return $unitObject->getAmount();
        }
    }

    /*...*/
}

Klasa Abstrakcyjna AbstractUnit (I ostatnia!)

/*Namespace*/
abstract class AbstractUnit implements InterfaceUnit
{
    protected $amount;

    public function __construct($amount)
    {
        $this->amount = $amount;
    }

    public function getAmount()
    {
        return $this->amount;
    }
}

Więc IDE podświetla mi:

/*getAmountUnits*/

return $this->units->getAmountUnits($nameArmy);

Jakobym zwracał void'a. :/

Muszę pogodzić się z tym jakże pięknym żółtym tłem czy da się jakoś ustalić więcej return w pętli?

Google'owałem:

http://stackoverflow.com/questions/3451906/multiple-returns-from-function

Ale array to ja nie chcę zwracać.


Panowie, bo Wy, jak na moje rozumowanie, zaczęliście rozwiązywać problem wywoływania „nieistniejącej” metody.

$unitObject->getAmount();

//Method 'getAmount' not found in subject class.

Tak w sumie to foreach z return już działa. Usunąłem return z:

    public function getAmountUnits($nameArmy)
    {
        /*tutaj był return*/ $this->units->getAmountUnits($nameArmy);
    }

I nie ma również komunikatu o voidzie.

Więc, wolę się upewnić, wasze rady dotyczą wywołania metody w sposób normalny, aby IDE nie zaznaczał jako nieznalezioną, czy z return?

Jeżeli tego drugiego, to nie narzekam - Bo wywoływanie tego w sposób jaki to robię niezbyt mnie satysfakcjonuje.

(Odpowiedź to: Nadal foreach() / Chodzi o wywoływanie nieistniejącej metody.)


Problem rozwiązany za pomocą wzorca: Composite.

Jestem bardzo - bardzo bardzo - początkującym we wzorcach, także nie powiedziałbym aby był to najlepszy wybór.

Obecnie poszukuję lepszego rozwiązania(Wzorca). :)

Kod:

[...Namespace...]

class Army extends CompositeUnit
{
    [...]
    public function amount() : int
    {
        $amountUnits = 0;
        foreach ($this->units as $unit) {
            $amountUnits += $unit->amount();
        }
        return $amountUnits;
    }
    [...]
}

Podobne do tego, co zaproponował Efik. Acz, na wzorzec DI jeszcze przyjdzie czas. :D

Więcej kodu, tutaj:

https://github.com/HaKIMus/oopfun/tree/feature

Dodatkowy okrojony ze wszystkiego i ułomny UML:

 

Miłego dnia, bądź nocy, a je lecę dalej czytać artykuły, aby skorzystać z lepszego rozwiązania.

komentarz zamknięcia: Problem rozwiązany.

2 odpowiedzi

+2 głosów
odpowiedź 24 października 2016 przez Comandeer Guru (601,590 p.)
wybrane 27 października 2016 przez HaKIM
 
Najlepsza
Stwórz tablicę, do której wrzucisz wszystkie wyniki i dopiero ją zwróć.

Albo generatory… ;)
komentarz 24 października 2016 przez HaKIM Szeryf (87,590 p.)
Lekki update tematu (Oddzielony kreską). Proszę o odpowiedź. : )

(Dalszych pytań nie będzie, tylko przejdę do działania i wybrania najlepszej ścieżki do rozwiązania problemu. (Pomysł z tablicą/generatorem, lub stworzenie osobnej klasy.))
komentarz 24 października 2016 przez Comandeer Guru (601,590 p.)
Hmm…  A czemu nie chcesz zwracać array?
komentarz 24 października 2016 przez efiku Szeryf (75,160 p.)

Jak dla mnie masz lekko przekombinowane rozwiązanie zwłaszcza  to getAmountUnits

Po nazwie metody spodziewam się, że otrzymam konkretną liczbę wszystkich jednostek. 

    public function getAmountUnits($nameArmy)
    {
        $amountUnits = 0;
        foreach ($this->units->get($nameArmy) as $unit) {
             $amountUnits += $unit->getAmount();
        }
        return $amountUnits;
    }

 

komentarz 24 października 2016 przez HaKIM Szeryf (87,590 p.)

Comandeer, jakoś tak lepiej dostać od razu 25 niżeli zagnieżdżone w kolejnych indeksach 25. 

Efik, dlaczego nie konkretnie getAmount(Units) a get? Abym mógł przechwytywać jakąkolwiek metodę bez tworzenia getów, czy? W sumie to wychodzę na jedno, tyle że wtedy będę musiał zaimplementować set :D 

https://github.com/HaKIMus/oopfun

Tak się trochę chciałem pobawić w abstrakcje, interfejsy, hermetyzacje, polimorfizm i chyba przesadziłem (Tzn. schrzaniłem).

 

komentarz 24 października 2016 przez efiku Szeryf (75,160 p.)
bo po prostu $this->units to kontener z jednostkami? Bo rzuci Ci notice dla nieistniejącej tablicy?

Tak, przekombinowałeś, albo się zgubiłeś.
komentarz 24 października 2016 przez HaKIM Szeryf (87,590 p.)

Tak, przekombinowałeś, albo się zgubiłeś.

Szczerze mówiąc to to i to.

Tzn. fajnie mi się operuje na tym wszystkim, bo sb. dodaję np. kolejny typ jednostki, IDE daje mi metdoy z inferface, abstracyjna załatwia set'y i działa jak cudo. Ale problem, jak na moje, to klasa Units i MakeUnits które przypominają mi teraz czystą powtarzalność kodu.

Ale dobrze takie rzeczy robić. Wiesz czego unikać. :D

Jak na moje to jakiegoś wzorca brakuje w tym projekcie.

+1 głos
odpowiedź 24 października 2016 przez Avernis Nałogowiec (27,400 p.)
Jeżeli chcesz zrobić kilka wyników to zrób strukturę lub klasę i ja zwracaj
komentarz 24 października 2016 przez HaKIM Szeryf (87,590 p.)
Za bardzo nie wiem o czym mówisz.

Nie chcę zwracać obiektu, tylko wynik metody getAmount() z klasy abstrakcyjnej.

Problem jedynie tkwi w tym, że chcę, aby nie było to za pośrednictwem print a return które, jak już wspominałem, zwraca pierwszy wynik i kończy działanie pętli.
komentarz 24 października 2016 przez Avernis Nałogowiec (27,400 p.)
Właśnie poprzez zwracanie własnego obiektu możesz zwrócić kilka wyników

 

http://php.net/manual/en/language.oop5.php
komentarz 24 października 2016 przez HaKIM Szeryf (87,590 p.)
edycja 24 października 2016 przez HaKIM

Aż tak ogólnikowy link w tym przypadku jest zbędny.

Poza tym, obiekt $army nie ma za bardzo dostępu do AbstractUnit.

Nadal nie jestem pewien, czy mówisz wciąż o tym, aby coś takiego zaimplementować w foreach() czy już jesteśmy na poziomie wywoływania funkcji getAmountUnits();


Dobra... Chyba coś łapię... Ale... O ile dobrze rozumuje to:

        foreach ($this->units[0][$nameArmy] as $index => $unitObject) {
            return $unitObject->getAmount();
        }

Klasa(Obiekt) jest już utworzona w $unitObject, więc... Raczej nie o to tu chodziło.

komentarz 24 października 2016 przez Avernis Nałogowiec (27,400 p.)
Chodzi o to że do nowo utworzonej klasy wrzucasz wszystko co chcesz przekazać przez return i ją zwracasz. Inaczej nie da się zwrócić kilka obiektów, no chyba że tablicą dynamiczną.
komentarz 24 października 2016 przez HaKIM Szeryf (87,590 p.)
Oke.

Zobaczymy co uda mi się zrobić.
komentarz 24 października 2016 przez HaKIM Szeryf (87,590 p.)
Lekki update tematu (Oddzielony kreską). Proszę o odpowiedź. : )

(Dalszych pytań nie będzie, tylko przejdę do działania i wybrania najlepszej ścieżki do rozwiązania problemu. (Rady od Comandeera z tablicą/generatorem, czy stworzenie osobnej klasy.))
komentarz 24 października 2016 przez Avernis Nałogowiec (27,400 p.)
Weź od commandera, on się zna lepiej na php

Podobne pytania

0 głosów
1 odpowiedź 123 wizyt
pytanie zadane 23 września 2020 w C i C++ przez Famous_D Nowicjusz (150 p.)
0 głosów
1 odpowiedź 1,322 wizyt
pytanie zadane 16 lipca 2017 w C i C++ przez Krystek102 Bywalec (2,440 p.)
0 głosów
2 odpowiedzi 336 wizyt
pytanie zadane 1 czerwca 2020 w PHP przez koterka Nowicjusz (210 p.)

92,579 zapytań

141,429 odpowiedzi

319,657 komentarzy

61,963 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...