Compare current record with previous record in loop/loop

Asked

Viewed 585 times

0

Setting

Let’s assume I have 100 records on any comic book.

ID | PESSOA | CARRETO | ENDERECO | DISTANCIA
1  |   A    |    C10  |    XX    |    20
2  |   B    |    C20  |    XY    |    25
3  |   D    |    C50  |    XZ    |    19
4  |   D    |    C50  |    XZ    |    19
5  |   F    |    C10  |    XW    |    27
...
...

From a query, I will generate an Array with all these records, and while doing the fetch, i need to check some conditions, comparing the previous record of the current record:

  • ID of reg. previous = ID reg. current -1
  • PESSOA of reg. previous = PESSOA reg. current
  • CARRETO of reg. previous = CARRETO reg. current
  • ENDERECO of reg. previous = ENDERECO reg. current
  • DISTANCIA of reg. previous = DISTANCIA reg. current

Example:

ID | PESSOA | CARRETO | ENDERECO | DISTANCIA
3  |   D    |    C50  |    XZ    |    19
4  |   D    |    C50  |    XZ    |    19

(If all conditions are true, I record the current record with the DISTANCIA = 0.)


As I did

In the loop I make the fetch, i used auxiliary variables to bring and compare the previous record check the conditions, and save the current in the array:

// variáveis auxiliares:
$id_ant = null; // seto como null para a 1a comparação
$pes_ant; $car_ant; $end_ant; $dis_ant;

while ($row = $result->fetch_assoc()) {

   // verifico as condições
   if ($id_ant == $row['ID']-1 && $pes_ant == $row['PESSOA'] && $car_ant == $row['CARRETO'] && $end_ant == $row['ENDERECO'] && $dis_ant == $row['DISTANCIA'])
       $row['DISTANCIA'] == 0;

   // gravo o registro no array
   $array[] = $row;

   // seto cada variável para depois utilizar na comparação posterior
   $id_ant = $row['ID']; 
   $pes_ant = $row['PESSOA']; 
   $car_ant = $row['CARRETO']; 
   $end_ant = $row['ENDERECO']; 
   $dis_ant = $row['DISTANCIA'];
}

Example of what the record would look like 4 in the array:

(
    [ID] => 4
    [PESSOA] => D
    [CARRETO] => C50
    [ENDERECO] => XZ
    [DISTANCIA] => 0
)

Doubts

  • What if I had a table with 100 columns to compare? Would I have to do all this one by one or has an "automatic" to do this?
  • It’s good that I’m doing this fetch or it would be better to play everything for an Array and then work on it? (thinking about performance)
  • That wouldn’t be the thing of a select distinct ? What you’re trying to do is stick with the ones that aren’t duplicated in every field ?

  • @Isac, no, I need them all. The only difference is treating if the condition is true, the distance is 0, but the record has to go too!

  • In the if you are using = in place of ==. And you need to compare all fields? Only the id and the name of pessoa would not be enough?

  • @Thiagomagalhães opa cara, essa do = was typing failure! I need to compare several, so I’m already thinking ahead if I have to compare 100 columns, understand!? rs

  • You could save everything in an array and then go through using foreach.. this way you could use a logic to go through the attributes and make the comparison.

  • @Thiagomagalhães then dude, I think you’re saying it the way that Gabriel.Elegrina posted it as an answer!?

  • It’s a way. And about passing it all on to array, thinking of performance, won or loss in this case would be minimal.

  • @Then Thiagomagalhães. But I do direct comparison on fetch is 1 step. Generate Array and then do foreach, would be 2 steps. If you catch a large volume, I believe it is considerable yes.

  • The step of generating a array computationally will have a time of linear = f(n). Then you will consume your time foreach + n, where n is the amount of results. Increase 1 n I consider it to be too little, if compared with (n^2) and (2^n), for example.

  • I don’t understand. If I do the fetchto generate the array, I run for example 10,000 records. Then mine foreach will have to go through the 10,000 records again. It’s not like this!?

Show 5 more comments

2 answers

-1

Try the example below:

//$array são todos os resultados da query ($result->fetch_all() )

if(count($array) > 1) { //verifica se existem mais de 1 item no array

  foreach ($array as $key => $atual) { //percorre o resultado da query

    if ($key > 0) { //compara se não é o primeiro item, pois este não terá item anterior

        $keyAnterior = $key - 1; //armazena o indice do registro anterior


        $anterior = $array[$keyAnterior]; //pega o item anterior do array

        if ($anterior['id'] == ($atual['id'] - 1)) { //comparar os ids (esta comparação ocorre devido a regra solicitada)

            unset($atual['id'], $anterior['id']); //remove a "coluna" id dos dois valores pois este ja foi comparado acima


            $saoIguais = $anterior === $atual; //compara se as colunas restantes do item anterior e do item atual são identicas

            if($saoIguais){
                //as demais colunas são iguais entre os itens
            }else{
                //as demais colunas são diferentes
            }

        } else {
            //a validação do id anterior == (id atual -1) não é verdadeira
        }
    }
  }
}

EDIT

Using the fetch_assoc method you can try this way:

$anterior = null;
while ($row < $result->fetch_assoc()) { //percorre pelo resultado da query
    $atual = $row; //utilizada variavel auxiliar pois o indice id será excluido do array, e precisaremos dele na proxima iteração

    if(!is_null($anterior)) { //verifica se o anterior não é null | primeira iteração
        if ($anterior['id'] == ($atual['id']) - 1) { //verificação do id

            unset($anterior['id'], $atual['id']); //remove o indice do item anterior e do atual

            if ($atual == $anterior) { //compara os indices restantes (podem ter N indices)
                echo "São iguais";
            } else {
                echo "São diferentes";
            }
        }
    }

    $anterior = $row; //atribui a variavel auxiliar ao item anterior
}

**Answer Question 1: ** Yes, it is possible to compare N indices with the equality operator ( == or ===);

**Questions answered 2: ** According to php.net Using the fetch_all() method will consume more memory as it returns all lines at once. In this specific case you still need to iterate each line with a loop, which can rather impact performance. However, for results of few lines is imperceptible.

I hope I’ve helped.

  • It would be good to explain what you did...

  • Oops, I’ll edit it

  • Hello Gabriel! First thank you for your answer, I understood her perfectly, I liked it. How are you using the array, there would be no way so already do this right in the fetch? And I would like to know about the second question, whether it is better to do in the fetch or treat in array as you did.

  • @Rbz takes a look at Edit. I hope it helps.

-1

Do so

<?PHP 
while ($row = $result->fetch_assoc()) {

   // verifico as condições
   if ($id_ant == $row && $row['ID']==$id_ant['ID']-1){
    $array[] = $row;
   }
   $id_ant = $row;
}
?>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.