Filtrowanie tablicy

0

Witam wszystkich serdecznie,

Aktualnie mam filtrowanie, które działa za pomocą sortowania a dokładnie funkcji usort na liście raportów. To z jakiej grupy raport ma być wyświetlony wybieram z selecta(jest tam 6 typów raportów). Każdy raport jest przypisany do jakiegoś typu raportów. Po wybraniu opcji z select wysyłany jest parametr za pomocą ajax w formie url i wykonuje się sortowanie. Problem polega na tym, że chciałbym aby te filtrowanie wyświetlało tylko i wyłącznie raporty z wybranym typem raportu a nie sortowało. Nie wiem jakiej funkcji mogę użyć żeby zastąpić te sortowanie macie jakiś pomysł? Aktualnie wygląda to tak:

} else if ($sortField == "support-request") {
            usort($caseList, function ($a, $b) {
                /* @var $a CMCase */
                $time1 = $a->caseType == 1;
                $time2 = $b->caseType == 1;
                return $time1 < $time2;
            });

I do każdego typu raportów jest oddzielne sortowanie.
Mam nadzieję, że coś mi pomożecie.
Pozdrawiam!

1

array_filter

0

Dziękuje za odpowiedź.

Aktualnie napisałem coś takiego :


else if ($sortField == "emergency") {
            $num = 5;
            /* @var $this CMCase */
            $item = $this->caseType == 1;
            array_filter($item, function($elem) use($num) {
                return $elem < $num;
            });
        }

 

Ale kod nie przechodzi. Nie do końca wiem za co odpowiada zmienna $num.

1

Twoim problem jest to, że piszesz kod na pałę.
Wiesz chociaż, że w swoim kodzie wykorzystałeś anonymous function (closure)? Prawdopodobnie gdybyś wiedział (najpierw przeczytawszy to w książce bądź poradniku), byłbyś w stanie wklepać w Google php closures i poczytać na temat znaczenia use w tym konkteście :P

0

To akurat wiem czytałem o array_filter bo tam jest zawarty a nie pomyślałem żeby poczytać o anonymous function (closure) i masz 100% racje ;)
Poczytam i dam znać jak poszło.
Dzięki ;)

0

A w jaki sposób mogę wyświetlić wybrane typy raportu według type_id za pomocą foreach'a? Aktualnie udaje mi się zamienić foreachem wszystkie typy na jakiś jeden co działa w ten sposób że zamienia mi wszystkie rodzaje na jeden ale to tylko nazwa się zmienia a ilość raportów ta sama a to nie na tym polega bo chce żeby wyświetlało mi tylko te wybrane. Czytałem o foreachu i rozumiem jak działa ale nie do końca wiem jak użyć go w moim wypadku.


foreach ($caseList as $caseFilter) {

                $customerTitle = null;
                $caseFilter->caseType = "1";
                $customer = CoreCompany::getWithId($caseFilter->customerId);
                if ($customer != null) {
                    $customerTitle = $customer->name;
                }
 
1

Rozważmy taki scenariusz

  1. Chcesz znaleźć mądrą dziewczynę

  2. Wiesz że blondynki nie są mądre (wybaczcie, taki przykład).

  3. Dochodzisz do wniosku że chcesz znaleźć tylko nie blondynki.

  4. (to co powinieneś zrobić) wczytać dziewczyny które nie mają blond włosów.

  5. (to co robisz) ładujesz wszystkie dziewczyny i farbujesz im włosy na czarno, licząc że wtedy przestaną być głupie.

Wracając do Twojego kodu. To że wczytasz elementy, a potem im zmienisz jakąś wartość, to nie zadziała tak że automatycznie ten obiekt będzie spełniał wszystkie warunki które chcesz.
Musisz wczytać odpowiednie obiekty, a nie wczytać wszystkie i potem je jakoś podmieniać.

0

Dziękuje Ci bardzo za pomoc pomogłeś mi uczę się dopiero i czasami brakuje mi logicznego myślenia też podstaw ... No ale niestety trzeba się uczyć!

Kod napisałem w ten sposób i całkiem dobrze działa mam tego filtrowania 8 opcji i kolejne opcje filtrowania są wykorzystane poprzez "else if" nie jest to optymalne według mnie bo tak na prawdę w 8 miejsach jest ten sam LOOP zrobiony tyle że parametr inny. Mogę to jakoś zoptymalizować ?

 

if ($filter == "support-request" && $search != null && $sortField != null && $order != null) {
            $list = $caseList;
            $caseList = null;
            foreach ($list as $case) {
                if ($case->caseType == CMCaseType::Support) {
                    $caseList[] = $case;
                }
            }

1

Pamiętaj że

if ($something != null) {

to to samo co

<if ($something) {

Poza tym nie rób nigdy $i == null albo $i != null bo w php to nie jest do końca deterministyczne, jak w javie.

Twój kod

if ($filter == "support-request" && $search != null && $sortField != null && $order != null)

można więc zapisać tak

if ($filter == 'support-request' && $search && $sortField && $order) {
0

To cały kod od filtrowania :


} else if ($filter == "support-request" && $search != null && $sortField != null && $order != null) {
            $list = $caseList;
            $caseList = null;
            foreach ($list as $case) {
                if ($case->caseType == CMCaseType::Support) {
                    $caseList[] = $case;
                }
            }

        } else if ($filter == "development-request" && $search != null && $sortField != null && $order != null) {
            $list = $caseList;
            $caseList = null;
            foreach ($list as $case) {
                if ($case->caseType == CMCaseType::Development) {
                    $caseList[] = $case;
                }
            }

        } else if ($filter == "installation-request-onsite" && $search != null && $sortField != null && $order != null) {
            $list = $caseList;
            $caseList = null;
            foreach ($list as $case) {
                if ($case->caseType == CMCaseType::InstallationOnSite) {
                    $caseList[] = $case;
                }
            }

        } else if ($filter == "installation-request-stationary" && $search != null && $sortField != null && $order != null) {
            $list = $caseList;
            $caseList = null;
            foreach ($list as $case) {
                if ($case->caseType == CMCaseType::InstallationStationary) {
                    $caseList[] = $case;
                }
            }

        } else if ($filter == "service-request-onsite" && $search != null && $sortField != null && $order != null) {
            $list = $caseList;
            $caseList = null;
            foreach ($list as $case) {
                if ($case->caseType == CMCaseType::ServiceOnSite) {
                    $caseList[] = $case;
                }
            }

        } else if ($filter == "service-request-stationary" && $search != null && $sortField != null && $order != null) {
            $list = $caseList;
            $caseList = null;
            foreach ($list as $case) {
                if ($case->caseType == CMCaseType::ServiceStationary) {
                    $caseList[] = $case;
                }
            }

        } else if ($filter == "miscellaneous" && $search != null && $sortField != null && $order != null) {
            $list = $caseList;
            $caseList = null;
            foreach ($list as $case) {
                if ($case->caseType == CMCaseType::Miscellaneous) {
                    $caseList[] = $case;
                }
            }

        } else if ($filter == "emergency" && $search != null && $sortField != null && $order != null) {
            $list = $caseList;
            $caseList = null;
            foreach ($list as $case) {
                if ($case->caseType == CMCaseType::Emergency) {
                    $caseList[] = $case;
                }
            }

        }

 
1

Najprostsze rozwiązanie:

$filterMap = [
	/* ... */
	'miscellaneous' => CMCaseType::Miscellaneous,
	'emergency' => CMCaseType::Emergency,
];

$filteredCaseList = [];

foreach ($cateList as $case) {
	if ($case->caseType === $filterMap[$filter]) {
		$filteredCaseList[] = $case;
	}
}
0

Zastanawia mnie jak za pomocą LOOP'a mogę zrobić sobie wyszukiwarkę i czy jest to możliwe bo fajnie by było poćwiczyć w ten sposób foreach'a.
Co o tym myślicie?

0

Zacznijmy może od tego, że takie rzeczy powinieneś robić wyłącznie po stronie bazy danych, a jeśli coś musisz filtrować już potem, to prawdopodobnie masz błąd w architekturze projektu ;-)

0

Udało mi się zrobić wyszukiwarkę poprzez wykorzystanie foreach'a ;) Wygląda to tak:

 
if ($filter && $searchOption == "search_customer" && $searchFraze && $sortField && $order) {

            $list = $caseList;
            $caseList = array();
            foreach ($list as $case) {
                if ($case->{"customerName"} == $searchFraze) {
                    $caseList[] = $case;
                }
            }
        }

Działa trochę słabo bo jeżeli chce wyszukać kogoś z tej tablicy muszę wpisać pełną nazwę inaczej wyświetla pustą tablicę :( Jak mogę zrobić by lepiej to filtrowało zwrócone wyniki? Próbowałem z operatorami logicznymi ale nie zbyt zadowalające wyniki otrzymywałem :(

1
  1. Nie $case->{"customerName"}, tylko $case->customerName.
  2. Poczytaj o wyrażeniach regularnych bądź w najprostszym przypadku strpos ;-)
  3. Nie searchFraze, tylko searchPhrase - nie bój się sprawdzać w słowniku.
0

Napisałem coś takiego ale rezultat mam ten sam :( Gdzie popełniłem błąd?

 
if ($searchOption == "search_customer" && $searchPhrase)  use ($searchPhrase) {
     $list = array_filter($caseList,function($case) {
        return stripos($case->customerName, $searchPhrase) !== false;
     });
}
0

Co Ci daje use ($searchPhrase) ulokowane tuż po ifie?

2
Sinres napisał(a)

Właśnie nic .. To gdzie powinienem ulokować use ($searchPhrase)?
http://blog.wilgucki.pl/2011/01/php-53-funkcje-anonimowe.html

1 użytkowników online, w tym zalogowanych: 0, gości: 1