Problem z przeskokiem indeksu w tablicy asocjacyjnej

0

Witam, podczas wyświetlania danych zauważyłam znacznymi przeskokami wartości indeksu tablicy. Przykłady poniżej:
Oryginalna ilość parametrów
Array ( [0] => parametr1 [1] => parametr2 [2] => parametr3 [3] => parametr4 [4] => parametr5 [5] => parametr6 [6] => parametr7 )

Po dodanych parametrach
Array ( [0] => parametr1 [1] => parametr2 [2] => parametr3 [3] => parametr4 [4] => parametr5 [5] => parametr6 [6] => parametr7 [7] => parametr8 [8] => parametr9 [9] => parametr10 [10] => parametr11 [11] => parametr12 [12] => parametr13 [13] => parametr14 [40] => parametr15 [82] => parametr16 [91] => parametr17 [92] => parametr18 [93] => parametr19 [94] => parametr20 )

Kod wygląda następująco:

$arrayMainParameters = [];
foreach($arrayCollectionsToFiltrate[$i]['parameters'] as $mainParameter)                        
 {
// print_r($mainParameter);
// echo "</br>";
 $arrayMainParameters[] = $mainParameter;                                                    
}
for($k = 0; $k < count($arrayCollectionsToFiltrate[$j]['parameters']); $k++)                                
{
      if(!in_array($arrayCollectionsToFiltrate[$j]['parameters'][$k], $arrayCollectionsToFiltrate[$i]['parameters']))         
      {
            $parameterToAdd = $arrayCollectionsToFiltrate[$j]['parameters'][$k];                        
            $arrayMainParameters[] = $parameterToAdd;
       }                        
}                   

Jest to fragment kodu w którym wykonuje iterację po informacjach o produktach pobranych z bazy danych. Po sprawdzeniu duplikatów produktów, wykonuję iterację po ich właściwościach ['parameters'], jeśli jakiś produkt ma dodatkowe parametry ($parameterToAdd) to są one dodawane do tablicy z parametrami ($arrayMainParameters) dla pierwszego wystąpienia danego produktu.
Chciałabym wiedzieć gdzie w kodzie popełniam błąd skutkujący przeskokiem indeksów ?

Dziękuję za wszelką pomoc

2

W tej pętli for jaką masz sprawdzasz warunek i dopiero jeśli jest prawdziwy dodajesz element do tej tablicy parametrów. Czyli nie każdy element będzie dodany.
Pisząc w pętli coś takiego:
$arrayMainParameters[] = $parameterToAdd; zdajesz się na automat wskazujący na klucz w konkretnej iteracji pętli. Zapis pustych nawiasów można by zastąpić

$x = 0;
$arr = [];
for(;;){
    $arr[$x] = 'this is iteretion number' . $x;
    $x++;
}
1

Zapis

$arrayMainParameters[] = $parameterToAdd;

doczepia na końcu pętli dodatkowy element. Nie ma znaczenia tutaj obrót pętli.

Problem w twoim kodzie leży tutaj:

foreach($arrayCollectionsToFiltrate[$i]['parameters'] as $mainParameter)                        
 {
// print_r($mainParameter);
// echo "</br>";
 $arrayMainParameters[] = $mainParameter;                                                    
}

Pętla dodaje wszystkie elementy z $arrayCollectionsToFiltrate[$i]['parameters'], nie ważne czy coś tam istnieje czy też nie.

Istnieją przynajmniej 2 rozwiązania tego problemu.

Najszybciej po prostu zresetować indeksy za pomocą:

array_values($arrayMainParameters)

pod koniec funkcji. Lub dodać warunek sprawdzający czy dodawany element nie jest NULL'em:

foreach($arrayCollectionsToFiltrate[$i]['parameters'] as $mainParameter) {
    if ($mainParametr)
        $arrayMainParameters[] = $mainParameter;                                                    
}

Poza tym, nie bardzo rozumiem samej logiki tego kodu. Powiedz, co chcesz osiągnąć?

0

@N3: Próbuję z kilku wystąpień tej samej kategorii (dla produktu) połączyć parametry (właściwości produktu) w jednej tablicy.
Poradzono mi bym posortowała tablicę asocjacyjną według kategorii a następnie wykonała pętle by móc połączyć parametry (unikalne) dotyczące konkretnej kategorii w jednej tablicy. Ogólnie udało się to zrobić z tym ,że tak jak napisałam w poście mam problem z indeksami. Spróbuję zastosować rozwiązania które zaproponowałeś.

0

Problem z indeksami rozwiązany. Do tablicy $arrayCollectionsToFiltrate[$i]['parameters'][] dodałam przy każdej iteracji nowe elementy pochodzące z kolejnego zestawu parametrów jeśli nie występują w głównej tablicy. Aktualnie kod wygląda tak:

$extendedParameters = [];
for($k = 0; $k < count($arrayCollectionsToFiltrate[$j]['parameters']); $k++)                              
{
      if(!in_array($arrayCollectionsToFiltrate[$j]['parameters'][$k], $arrayCollectionsToFiltrate[$i]['parameters']))         // sprawdzenie czy parametru z duplikatu nie ma w glownych parametrach 
        {
              if($arrayCollectionsToFiltrate[$j]['parameters'][$k] != "0")
              {
                       $arrayCollectionsToFiltrate[$i]['parameters'][] = $arrayCollectionsToFiltrate[$j]['parameters'][$k];            // jesli takiego parametru nie ma to zostaje on dodany do tablicy z glownymi parametrami
                       $extendedParameters[] = $arrayCollectionsToFiltrate[$i]['parameters'];
               }
          }                        
   }
echo "uzupelnione parametry: </br>"; 
print_r($extendedParameters);
echo "</br>";

Wiem, że teraz będę mieć kilka tablic w jednej ale będę mogła tą najdłuższą (ostatnią) ze wszystkimi parametrami pobrać.
Dziękuję za porady

0
kasia13130 napisał(a):

Problem z indeksami rozwiązany. Do tablicy $arrayCollectionsToFiltrate[$i]['parameters'][] dodałam przy każdej iteracji nowe elementy pochodzące z kolejnego zestawu parametrów jeśli nie występują w głównej tablicy. Aktualnie kod wygląda tak:

$extendedParameters = [];
for($k = 0; $k < count($arrayCollectionsToFiltrate[$j]['parameters']); $k++)                              
{
      if(!in_array($arrayCollectionsToFiltrate[$j]['parameters'][$k], $arrayCollectionsToFiltrate[$i]['parameters']))         // sprawdzenie czy parametru z duplikatu nie ma w glownych parametrach 
        {
              if($arrayCollectionsToFiltrate[$j]['parameters'][$k] != "0")
              {
                       $arrayCollectionsToFiltrate[$i]['parameters'][] = $arrayCollectionsToFiltrate[$j]['parameters'][$k];            // jesli takiego parametru nie ma to zostaje on dodany do tablicy z glownymi parametrami
                       $extendedParameters[] = $arrayCollectionsToFiltrate[$i]['parameters'];
               }
          }                        
   }
echo "uzupelnione parametry: </br>"; 
print_r($extendedParameters);
echo "</br>";

Wiem, że teraz będę mieć kilka tablic w jednej ale będę mogła tą najdłuższą (ostatnią) ze wszystkimi parametrami pobrać.
Dziękuję za porady

Mega pokręcony ten kod - ani trochę nie rozumiem co się w nim dzieje. Może mogłabyś pokazać przykładowy input, i pokazać jaki output chciałabyś osiągnąć?

0

Tak jak wspomniałam w poście, jest to fragment kodu. Pętla for przebiega przez parametry (właściwości) każdej kolekcji produktu, następnie jeśli parametr z duplikatu kolekcji znajduje się w pierwszym wystąpieniu tej kolekcji to tablica zawierająca podstawowe parametry jest poszerzana o ten dodatkowy parametr. Następnie poszerzona tablica parametrów jest dodawana do głównej tablicy zainicjalizowanej przed pętlą for. Przykładowy input jest taki:
Array ( [0] => Array ( [collection] => Kolekcja-1 [parameters] => Array ( [0] => parametr1 [1] => parametr2 [2] => parametr3 [3] => parametr4 [4] => parametr5 [5] => parametr6 ) ) [1] => Array ( [collection] => Kolekcja-2 [parameters] => Array ( [0] => parametr1 [1] => parametr2 [2] => parametr3 ) ) [2] => Array ( [collection] => Kolekcja-2 [parameters] => Array ( [0] => parametr1 [1] => parametr2 [2] => parametr3 ) ) [3] => Array ( [collection] => Kolekcja-2 [parameters] => Array ( [0] => parametr1 [1] => parametr2 [2] => parametr3 ) ) [4] => Array ( [collection] => Kolekcja-2 [parameters] => Array ( [0] => parametr1 [1] => parametr2 [2] => parametr3 ) ) [5] => Array ( [collection] => Kolekcja-2 [parameters] => Array ( [0] => parametr1 [1] => parametr2 [2] => parametr3 ) ) [6] => Array ( [collection] => Kolekcja-2 [parameters] => Array ( [0] => parametr1 [1] => parametr2 [2] => parametr3 ) ) [7] => Array ( [collection] => Kolekcja-2 [parameters] => Array ( [0] => parametr1 [1] => parametr2 [2] => parametr3 ) ) [8] => Array ( [collection] => Kolekcja-3 [parameters] => Array ( [0] => parametr1 [1] => parametr2 [2] => parametr3 [3] => parametr4 [4] => parametr5 ) ) [9] => Array ( [collection] => Kolekcja-4 [parameters] => Array ( [0] => parametr1 [1] => parametr2 [2] => parametr3 [3] => parametr4 [4] => parametr5 [5] => parametr6 [6] => parametr7 [7] => parametr8 [8] => parametr9 ) ) [10] => Array ( [collection] => Kolekcja-5 [parameters] => Array ( [0] => parametr1 [1] => parametr2 [2] => parametr3 [3] => parametr4 [4] => parametr5 [5] => parametr6 [6] => parametr7 [7] => parametr8 ) )
output jaki potrzebuję uzyskać:
Array ( [0] => Array ( [collection] => Kolekcja-1 [parameters] => Array ( [0] => parametr1 [1] => parametr2 [2] => parametr3 [3] => parametr4 [4] => parametr5 [5] => parametr6 ) ) [1] => Array ( [collection] => Kolekcja-2 [parameters] => Array ( [0] => parametr1 [1] => parametr2 [2] => parametr3 [3] => parametr4 (dodatkowy_parametr_z_duplikatu) [4] => parametr5 (dodatkowy_parametr_z_duplikatu) [7] => parametr8 (dodatkowy_parametr_z_duplikatu) [8] => parametr9 (dodatkowy_parametr_z_duplikatu) [9] => parametr10 (dodatkowy_parametr_z_duplikatu) [10] => parametr11 (dodatkowy_parametr_z_duplikatu) [11] => parametr12 (dodatkowy_parametr_z_duplikatu) [12] => parametr13 (dodatkowy_parametr_z_duplikatu) [13] => parametr14 (dodatkowy_parametr_z_duplikatu)) [2] => Array ( [collection] => Kolekcja-3 [parameters] => Array ( [0] => parametr1 [1] => parametr2 [2] => parametr3 [3] => parametr4 [4] => parametr5 ) ) [3] => Array ( [collection] => Kolekcja-4 [parameters] => Array ( [0] => parametr1 [1] => parametr2 [2] => parametr3 [3] => parametr4 [4] => parametr5 [5] => parametr6 [6] => parametr7 [7] => parametr8 [8] => parametr9 ) ) [4] => Array ( [collection] => Kolekcja-5 [parameters] => Array ( [0] => parametr1 [1] => parametr2 [2] => parametr3 [3] => parametr4 [4] => parametr5 [5] => parametr6 [6] => parametr7 [7] => parametr8 ) )

1
kasia13130 napisał(a):

Tak jak wspomniałam w poście, jest to fragment kodu. Pętla for przebiega przez parametry (właściwości) każdej kolekcji produktu, następnie jeśli parametr z duplikatu kolekcji znajduje się w pierwszym wystąpieniu tej kolekcji to tablica zawierająca podstawowe parametry jest poszerzana o ten dodatkowy parametr. Następnie poszerzona tablica parametrów jest dodawana do głównej tablicy zainicjalizowanej przed pętlą for. Przykładowy input jest taki:

[..]
output jaki potrzebuję uzyskać:
[..]

Yyyy... czyli po prostu chcesz pogrupować parametry w Twoich elementach, tam gdzie mają wspólną nazwę "collection"? Czemu nie mówiłeś od początku.

Mogłabyś po prostu zrobić tak?

<?php
function groupParametersByCollection(array $input): array
{
    $result = [];
    foreach ($input as $item) {
        $collection = $item['collection'];
        if (array_key_exists($collection, $result)) {
            $result[$collection]['parameters'] = array_merge($result[$collection]['parameters'], $item['parameters']);
        } else {
            $result[$collection] = $item;
        }
    }
    return array_values($result);
}

Użycie

$groupped = groupParametersByCollection($arrayCollectionsToFiltrate);

Jedna pętla zamiast dwóch, czytelny kod, użycie array_merge() zamiast ręcznego łączenia array'ów.

0

@TomRiddle: Bardzo dziękuje, faktycznie dużo prostsze niż mój sposób.

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