Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Problem z funkcją + in_array()
Forum PHP.pl > Forum > PHP
grabarz5
Witam.
Przesiedziałem chyba godzinę nad znalezieniem problemu. Bezskutecznie. Idąc w myśl powiedzenia "co dwie głowy to nie jedna", zamieszczam kod pewnej funkcji:
  1. function translate($tString){
  2. $dictionary = file('dictionary.txt');
  3.  
  4. for($i=0; $i<count($dictionary); $i++){
  5. $rawVerb = explode(' ', $dictionary[$i]);
  6. $dVerb[] = $rawVerb[0];
  7. $pVerb[] = $rawVerb[1];
  8. }
  9.  
  10. $rawString = explode(' ',$tString);
  11.  
  12. for($x=0; $x<count($rawString); $x++){
  13. if(in_array($rawString[$x], $pVerb)){
  14. echo $eString[] = $dVerb[$nx];
  15. }
  16. }
  17. return $eString;
  18. }


Funkcja na wejściu otrzymuje wartość pola tekstowego.
Plik dictionary.txt jest zwykłym plikiem tekstowym. Sam plik odczytywany jest poprawnie. Problem leży przy zmiennej $eString, która zwyczajnie, wg interpretera, sobie nie istnieje. Nie potrafię znaleźć powodu.

Z góry bardzo dziękuję za pomoc
mstraczkowski
Na pierwszy rzut oka, linijka 14 - używasz zmiennej $nx, która nie istnieje.

Dodatkowo proponowałbym zadeklarować sobie zmienną $eString wcześniej jako np. pusta tablica.
Zwracasz ją w wyniku funkcji, a nie zawsze będzie ona wypełniania (musi być spełniony konkretny warunek)

Dzięki temu, funkcja zwróci ci pustą tablicę zamiast NULL + notice w przypadku gdy nie dojdzie do jej wypełniania.
grabarz5
Rzeczywiście. Przeoczyłem ten szczegół. Jest to pozostałość po poprzedniej pętli. Generalnie wcześniej wyglądało to tak:
  1. for($x=0; $x<count($rawString); $x++){
  2. for($nx=0; $nx<count($pVerb) ; $nx++) {
  3. if(stripos($rawString[$x], $pVerb[$nx]){
  4. echo $eString[] = $dVerb[$nx];
  5. }
  6. }

I to też nie działało. Potem zajżałem do dokumentacji i znalazłem funkcję in_array().

Ps. Pisałem teraz z pamięci, ale wydaje mi się, że jest dobrze.
mstraczkowski
Na tyle na ile mogę zrozumieć cel działania tej funkcji, to wydaje mi się, że posiadasz błędne dane w pliku tekstowym.
Albo odczytujesz je w nieprawidłowy sposób (może za mało lub za dużo spacji w explode)

Gdy utworzyłem sobie skróconą wersję twojej funkcji z danymi na sztywno w tablicy (bez czytania z pliku)
To wydaje mi się, że otrzymywany wynik jest prawidłowy.

I jeszcze jedna uwaga, funkcja in_array odróżnia wielkość liter (to znaczy, że np Mam != mam)

  1. function translate($tString){
  2.  
  3. $pVerb = array('Mam', 'na', 'imie', 'Maciek');
  4. $dVerb = array('My', 'name', 'is', 'Maciek');
  5.  
  6. $rawString = explode(' ',$tString);
  7.  
  8. for($x=0; $x<count($rawString); $x++){
  9. if(in_array($rawString[$x], $pVerb)){
  10. $eString[] = $dVerb[$x];
  11. }
  12. }
  13. return $eString;
  14. }
  15.  
  16. var_dump(translate('Mam na imie Maciek'));
grabarz5
Funkcja file() wczytuje plik do tablicy.
Dane w pliku wyglądają tak :
Wartość1<tab>wartość2<koniec linii>

I tak prawie 300 linii.
Wszystko powinno być dobrze w tym pliku, ale jeszcze się upewnię.

Rozumiem, że jeśli chcę ignorować wielkość znaków, to muszę zastosować swoją podwójną pętlę? Czy jest jakaś inna funkcja do tego?

Jeszcze tak wpadło mi do głowy...
Z tego co się orientuję, PHP posiada chyba jakieś funkcje do plików CSV. Jeśli tak, to może potraktować ten plik takimi funkcjami?
kreatiff
Spróbuj taką zmianę przy wczytywaniu pliku słownika:
  1. $dictionary = file('dictionary.txt', FILE_IGNORE_NEW_LINES);
Przy przyrównywaniu wyrazów można w nich zmienić wszystkie literki na małe za pomocą strtolower.

Jeszcze jedna wskazówka, by zoptymalizować trochę skrypt, a mianowicie, taki zapis
  1. for($i=0; $i<count($dictionary); $i++){
powoduje liczenie wielkości tablicy $dictionary przy każdej iteracji. Nie ma to sensu, bo jej wielkość się nie zmienia. Można to zastąpić tym:
  1. for($i=0, $j=count($dictionary); $i<$j; $i++){
grabarz5
kreatiff -> niestety nie działa :/ Optymalizację zastosowałem i zapamiętam na przyszłość. Dzięki za wskazówkę wink.gif

Dla pewności zamieszczam poniżej fragment pliku tekstowego:

  1. Aak Przewodnik, Wskazówka, Doradca
  2. Aam Hmm?
  3. Aar Sługa
  4. Aav Dołączyć
  5. Aaz Litość
  6. Ag Spalić
  7. Ah Polować
  8. Ahmik Usługa
  9. Ahmul Mąż
  10. Ahkrin Odwaga
  11. Ahraan Rana
  12. Ahrk I
  13. Ahrol Wzgórze/Góra
  14. Ahzid Gorzki
  15.  
  16. (...)


Dla całkowitej pewności zamieszczam cały plik PHP:

  1. <?php
  2. header('charset=UTF-8');
  3.  
  4. <form action="dragon.php" method="POST">
  5. <textarea name="tBox" style="width: 700px; height: 250px;">'.@$_POST['tBox'].'</textarea>
  6. <input type="submit" value="OK">
  7. </form>
  8. ');
  9.  
  10. if(isset($_POST['tBox'])){
  11. print_r(translate($_POST['tBox']));
  12. }
  13.  
  14. function translate($tString){
  15. $dictionary = file('dictionary.txt', FILE_IGNORE_NEW_LINES);
  16.  
  17. for($i=0; $i<count($dictionary); $i++){
  18. $rawVerb = explode(' ', $dictionary[$i]);
  19. $dVerb[] = $rawVerb[0];
  20. $pVerb[] = $rawVerb[1];
  21. }
  22.  
  23. $rawString = explode(' ',$tString);
  24.  
  25. for($x=0; $x<count($rawString); $x++){
  26. for($x=0, $j = count($rawString); $x<$j; $x++){
  27. if(in_array($rawString[$x], $pVerb)){
  28. $eString[] = $dVerb[$x];
  29. }
  30. }
  31. }
  32. return $eString;
  33. }
  34. ?>
kreatiff
W kodzie powyżej jest coś namieszane z deklarowaniem $x w pętlach. Jest to robione podwójnie.

Poniżej jak ja bym to zrobił, może coś z tego się przyda:
  1. $tString = 'Aak Aam Aar';
  2.  
  3. $dictionary = file('dictionary.txt', FILE_IGNORE_NEW_LINES);
  4. foreach ( $dictionary as $linia ) {
  5. $linia = explode("\t", $linia);
  6. $dVerb[] = $linia[0];
  7. $pVerb[] = $linia[1];
  8. }
  9. $eString = str_replace($dVerb, $pVerb, $tString);
  10.  
  11. echo $eString;
Ogólnie jest to bardzo niedoskonałe, ale z prostym zamienianiem wyrazów sobie poradzi.
grabarz5
No właśnie...
Dawno nie robiłem w PHP i w ogóle zapomniałem o istnieniu foreach...
Zaraz sprawdzę, Twoją propozycję. Dzięki wielkie smile.gif

No proszę. Działa biggrin.gif
Co prawda trzeba jeszcze wprowadzić parę poprawek, głównie to, aby ignorował wielkość liter + kilka innych, ale z tym powinienem sobie poradzić. Mimo wszystko nadal mnie zastanawia czemu mój pierwotny skrypt nie działał. Na logikę raczej powinien... dziwne to.

Dzięki wszystkim za pomoc smile.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.