Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] Tablica - unikalne ścieżki ale nie do końca
Forum PHP.pl > Forum > Przedszkole
lolek92
Witam wszystkich,

Mam problem z wyciągnięciem z tablicy unikalnych ścieżek.

Tablica wygląda przykładowo:
  1. <?php
  2. (
  3.    [0] => 31
  4.    [1] => 31.1
  5.    [2] => 31.1.17
  6.    [3] => 31.1.17.18
  7.    [4] => 31.2
  8.    [5] => 31.2.13
  9. )
  10. ?>


oczywiście nie zawsze najdłuższa ścieżka jest na dole,
chcę aby pozostały tylko najdłuższe ścieżki, czyli:

  1. <?php
  2. (
  3.    [0] => 31.1.17.18
  4.    [1] => 31.2.13
  5. )
  6. ?>


Próbowałem array_unique i funkcji z forum, ale nie działają prawidłowo.

Proszę was o pomoc, z góry dziękuje wszystkim za chęci.

Pozdrawiam
erix
Typuj wszystkie wartości na string.
lolek92
Ale w jakim sensie, bo nie rozumiem?

Jeżeli ścieżka będzie stringiem to co to zmieni?
thomas2411
Traktuj wartości z tabeli jako stringi. Poczytaj sobie tu Strings" title="Zobacz w manualu PHP" target="_manual Converting to string
lolek92
Nie wiem o co wam chodzi, może źle napisałem bo ja nie mam takiego kodu

  1. <?php
  2. (
  3.    [0] => 31
  4.    [1] => 31.1
  5.    [2] => 31.1.17
  6.    [3] => 31.1.17.18
  7.    [4] => 31.2
  8.    [5] => 31.2.13
  9. )
  10. ?>


tylko to jest wynik z wyświetlenia tablicy print_r($tab), chyba że wam chodzi o to aby tę tablicę przekształcić na taką:

  1. <?php
  2. (
  3.    [0] => '31'
  4.    [1] => '31.1'
  5.    [2] => '31.1.17'
  6.    [3] => '31.1.17.18'
  7.    [4] => '31.2'
  8.    [5] => '31.2.13'
  9. )
  10. ?>


Czytałem w manualu to co mi podałeś ale tam jest tego tyle że nie wiem o co chodzi, więc poszukałem w google ale nie znalazłem odpowiedzi, jedynie w manualu funkcja strval() i settype()
erix
No to ciepło szukasz.

  1. <?php
  2. (string)$zmienna[0];
  3. ?>

A jak przeiterować - pomyśl. [;

Musisz zamienić, gdyż float nie da się porównywać ze 100% dokładnością.
lolek92
żeby wyciągnąć pierwszą literę to $zmienna[0][0] drugą $zmienna[0][1] itd.

a co do konwertowania na string to mam teraz tak:
  1. <?php
  2. for($x=0;$x<count($kategoria);$x++){
  3.        (string)$kategoria[$x];
  4.    }
  5. ?>
erix
No i ok, nienajgorzej.

Ale:
  • liczbę wpisów w tablicy zapisuj do zmiennej; nie zliczaj w pętli
  • pierwsza litera:
    1. <?php
    2. $zmienna[1]{0}
    3. ?>
    nie pamiętam, czy wywalało notice, ale chyba było wolniejsze, bo najpierw sprawdzało, czy zmienna, to nie tablica. O lepszej czytelności nie wspomnę (wtedy wiadomo, że chodzi o łańcuch tekstowy, a nie klucz tablicy).
lolek92
No dobra ale jak to porównywać bo jak na razie to w sumie nic się nie zmieniło, bo najbardziej to mi chodziło żebyście mi pomogli właśnie w porównywaniu i zwróceniu odpowiedniej tablicy bo tego nie wiem jak zrobić, no ale oczywiście to też się przyda na przyszłość.

Więc jeśli chodzi o porównywanie to wiem że na pewno trzeba pętle i funkcje która będzie porównywać ciągi i tu jest problem jak to rozpisać żeby wszystko dobrze porównało?
erix
Hmm, to chciałeś w końcu wyciągać najdłuższe, czy porównywać...?

Bo trochę zamotałeś...
lolek92
no chcę wyciągnąć najdłuższe ścieżki ale które się powtarzają
z tego:

[0] => 31
[1] => 31.1
[2] => 31.1.17
[3] => 31.1.17.18
[4] => 31.2
[5] => 31.2.13

ma zostać:

[0] => 31.1.17.18
[1] => 31.2.13

bo reszta się powtarza,
czyli chcę żeby zostały najdłuższe ścieżki bez krótszych które się powtarzają
erix
To array_unique" title="Zobacz w manualu PHP" target="_manual nie styka...?

Do tego konkretnego przypadku by pasował.
lolek92
no ale właśnie nie działa chyba że da rady jakieś opcje dodać, ale o to chodzi że ta ścieżka może być dużo dłuższa
Pr0100
  1. <?php
  2. $temp = $values = array('31', '31.1', '31.1.17', '31.1.17.18', '31.2', '31.2.13');
  3.  
  4. rsort($temp);
  5. $row_map = $toDelete = array();
  6.  
  7. foreach ($temp as $row)
  8. {
  9.  $current_row_map = explode('.', $row);
  10.  
  11.  if (!is_null($row_map))
  12.  {
  13.    
  14.    $row_map_cont = count($row_map);
  15.    $current_row_map_cont = count($current_row_map);
  16.  
  17.    if ($current_row_map_cont+1 == $row_map_cont)
  18.    {
  19.  
  20.      $similar = TRUE;
  21.        
  22.      for ($i=0; $i <= $current_row_map_cont-1; $i++)
  23.      {
  24.        
  25.        if ($current_row_map[$i] != $row_map[$i])
  26.        {
  27.          $similar = FALSE;
  28.          break;
  29.        }
  30.      }
  31.  
  32.      if ($similar == TRUE)
  33.      {
  34.        $toDelete[] = $row;
  35.      }
  36.    }
  37.  }
  38.  
  39.  $row_map = $current_row_map;
  40. }
  41.  
  42.  
  43. foreach($toDelete as $row)
  44. {
  45.  unset($values[array_search($row, $values)]);
  46. }
  47.  
  48. $values = array_values($values);
  49. ?>
lolek92
Pr0100 dzięki wielkie na takie coś to bym nigdy nie wpadł, zaraz sobie przeanalizuje dokładniej jak to zrobiłeś, jeszcze raz dzięki - jesteś wielki
Łukasz O.
i po co takie zamotanie?

  1. <?php
  2. $tab = array(
  3.    '31',
  4.    '31.1',
  5.    '31.1.17.18',
  6.    '31.1.17.18.24',
  7.    '31.1.17',
  8.    '31.1.17.18.24.56',
  9.    '31.2',
  10.    '31.2.13',
  11.    '31.1.17.18.24.56.78.12',
  12. );
  13. arsort($tab);
  14.  
  15. $wynik = array();
  16. foreach($tab as $wartosc){
  17.    $dodaj = true;
  18.    foreach($wynik as $klucz){
  19.        if( strpos( $klucz, $wartosc ) === 0 ){
  20.            $dodaj = false;
  21.        }
  22.    }
  23.    $dodaj AND $wynik[] = $wartosc;
  24. }
  25. var_export($wynik);
  26.  
  27. /* wynik
  28. array (
  29.   0 => '31.2.13',
  30.   1 => '31.1.17.18.24.56.78.12',
  31. );
  32. */
  33. ?>
Pr0100
Cytat
i po co takie zamotanie?


1. Wydajność
2. Brak sortowania danych wyjściowych
lolek92
Łukasz O. dzięki, widzę że są na tym forum ludzie którzy mnie rozumieją i chcą pomóc, poprzedni kod był trochę zamotany a wystarczyło tylko dobrze pomyśleć - ta głowa,

dzięki wszystkim którzy chcieli pomóc

Pozdr. for all

Pr0100 to co ten twój wydajniejszy, bo ja i tak wkładam ten skrypt do funkcji

Pr0100 jednak twój lepiej działa bo w tym Łukasza jest błąd jeżeli jest: 1.1.1 i 1.1.11 wtedy usuwa 1.1.1 a w rzeczywistości są inne więc powinny posostać oba
Łukasz O.
linia 20: if( strpos( $klucz, $wartosc.'.' ) === 0 ){ // dodajesz kropkę, aby potwierdzić, że to podciąg rodzica

@Pr0100 nie chce mi się robić testów wydajnościowych, bo to gruba przesada będzie, ale zwróć uwagę na to, iż:
1) sortowanie wyniku nie ma nic do rzeczy, bo i tak obaj nie zachowujemy porządku kluczy,
2) robisz dokładnie to samo co ja, ale niepotrzebnie komplikując kod
3) Twój skrypt działa niepoprawnie:
moje dane wejściowe, Twoja funkcja, wynik:
array ( 0 => '1.1.11', 1 => '31.1.17.18.24.56', 2 => '31.2.13', 3 => '1.1.1', 4 => '31.1.17.18.24.56.78.12', )

wartość pod kluczem 1 jest podciągiem 4

mały test: http://pastebin.com/f2d4bbd26
moja wersja jest przeszło 2x szybsza

poprawiona wersja
  1. <?php
  2. $tab = array(
  3.    '1.1.11',
  4.    '31',
  5.    '31.1',
  6.    '31.1.17.18',
  7.    '31.1.17.18.24',
  8.    '31.1.17',
  9.    '31.1.17.18.24.56',
  10.    '31.2',
  11.    '31.2.13',
  12.    '1.1.1',
  13.    '31.1.17.18.24.56.78.12',
  14. );
  15. rsort($tab);
  16.  
  17. $wynik = array($tab[0]);
  18.  
  19. $ilosc = count($tab);
  20. for($i = 0; $i < $ilosc; $i++){
  21.    $t1 = explode('.',$tab[$i]);
  22.    $t2 = explode('.',$tab[$i+1]);
  23.    $test = array_diff_assoc($t2,$t1);
  24.    $test = !empty($test);
  25.    if( isset($tab[$i+1]) && $test ){
  26.        $wynik[] = $tab[$i+1];
  27.    }
  28. }
  29. var_export($wynik);
  30. ?>


KU PAMIĘCI
Pr0100
Cytat
Twoja funkcja, wynik:
array ( 0 => '1.1.11', 1 => '31.1.17.18.24.56', 2 => '31.2.13', 3 => '1.1.1', 4 => '31.1.17.18.24.56.78.12', )

wartość pod kluczem 1 jest podciągiem 4


autor tematu chyba nie przewidział takiej funkcjonalności (przynajmniej ja go tak zrozumiałem) smile.gif

Cytat
moja wersja jest przeszło 2x szybsza


Ta tak ale poprzednia z:

  1. <?php
  2. foreach($wynik as $klucz){
  3.  if( strpos( $klucz, $wartosc ) === 0 ){
  4.    $dodaj = false;
  5.  }
  6. }
  7. ?>


już chyba nie smile.gif Mam prace, nie mam czasu robić testów, poza tym taką walkę "na kod" uważam za bardzo próżną. Zresztą dużo będzie zależeć od danych które zostały wprowadzone (zależność pomiędzy ilością elementów a ilością kropek w pojedynczym elemencie). O i jeszcze twój skrypt sortuje elementy a autor tematu chciał je tylko przefiltrować....
Łukasz O.
walka na kod nigdy nie jest próżna - pomaga w rozwijaniu umiejętności szybkiego myślenia i reagowania na zmienne dane wejściowe - nie odbieraj tego jako ataku biggrin.gif nie taki mój cel w tym
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.