Sort phone numbers in a string

Asked

Viewed 370 times

5

I have some phone numbers, mobile and fixed, in a database, I used the function implode()to join them together in the same string, getting that way:

(11) 3333-4353  (11) 98000-2222 (11) 3027-5555 (11) 97000-0333

What I want to do is sort them with preference to mobile phones, ie after the DDD (xx) the numbers that have 9,8,7 in front will be ordered at the beginning, what is the best way to do this?

  • In this example you gave, how would it be ordered? "(11) 97000-0333 (11) 98000-2222 (11) 3027-5555 (11) 3333-4353" or simply "(11) 98000-2222 (11) 97000-0333 (11) 3333-4353 (11) 3027-5555"?

  • Since I only used examples of initials 3 and 9, the two numbers with 9 would be in front and rest behind

  • Just following the order of 9,8,7 is already good, the rest is indifferent.

  • I don’t think regex is the best way to solve this, maybe some function that takes the second number and sorts?

  • php would no longer sort this for you using ORDER BY DESC ?

3 answers

5

Hello, use the function usort, with it you define a function that validates the order, the return of this function should be -1 or 1. It is applied in arrays to perform comparison.

See how it would look:

<?php

$telefones = array(
    "(11) 3333-4353",
    "(11) 98000-2222",
    "(11) 3027-5555",
    "(11) 97000-0333",
);

function sortNumber($a, $b) {
    $a = preg_replace('/\D/', '', $a);
    $b = preg_replace('/\D/', '', $b);
    return ($a > $b) ? -1 : 1;
}

usort($telefones, 'sortNumber');

print_r($telefones);

?>

Upshot:

Array
(
    [0] => (11) 98000-2222
    [1] => (11) 97000-0333
    [2] => (11) 3333-4353
    [3] => (11) 3027-5555
)

An example of using this application within a full example class:

<?php

class Telefones
{
    // Variável com os telefones
    private $telefones = array();

    // Construtor para enviar os telefones
    public function __construct($telefones)
    {
        if( is_array($telefones) )
        $this->telefones = $telefones;
    }

    // Funcão para ordenar
    public function ordernarTelefones()
    {
        $telefones = $this->telefones;      
        usort($telefones, array($this, 'sortNumber'));
        $this->telefones = $telefones;

        return $this;
    }

    // Função para resgatar os dados
    public function pegarTelefones()
    {
        return $this->telefones;
    }

    // Função auxiliar customizada com regra de ordenar
    private function sortNumber($a, $b)
    {
        $a = preg_replace('/\D/', '', $a);
        $b = preg_replace('/\D/', '', $b);
        return ($a > $b) ? -1 : 1;
    }

}

$array = array(
    "(11) 3333-4353",
    "(11) 98000-2222",
    "(11) 3027-5555",
    "(11) 97000-0333",
);

$telefones = new Telefones($array);

print_r(
    $telefones
        ->ordernarTelefones()
        ->pegarTelefones()
);

?>

Upshot:

Array
(
    [0] => (11) 98000-2222
    [1] => (11) 97000-0333
    [2] => (11) 3333-4353
    [3] => (11) 3027-5555
)
  • How would you use a class scope? "$this->sortNumber", same quotes?

  • @NGTHM4R3, you can use as follows: usort($phones, array($this, 'sortNumber'))

  • @NGTHM4R3 put an example of using with class.

3

If you are using php you can use ORDER BY DESC

example with Mysqli

    $sql=("SELECT coluna FROM Tabela ORDER BY coluna DESC"); 

    $result = mysqli_query($link,$sql);

    while($row = mysqli_fetch_assoc($result)) {
        $tels .=$row["cel_cli"]. " ";
    }

    echo $tels;

inserir a descrição da imagem aqui

inserir a descrição da imagem aqui

0

There is no information about the origin of these data, if the answer from @Leo Caracciolo is sufficient. In general cases, such as where you are reading from the file you can use the usort, as already indicated. However, if the DDD does not matter you can omit them:


$telefones = [
    '(11) 3333-4353',
    '(11) 98000-2222',
    '(11) 3027-5555',
    '(11) 97000-0333',
    '(12) 99999-9999',
    '(12) 88888-8888',
    '(13) 11111-1111'

];


usort($telefones, function ($a, $b) {
    return strtr(substr($a, 5), ['-' => '']) <=> strtr(substr($b, 5), ['-' => '']);
});

This will result in:

array(7) {
  [0]=>
  string(14) "(11) 3027-5555"
  [1]=>
  string(14) "(11) 3333-4353"
  [2]=>
  string(15) "(13) 11111-1111"
  [3]=>
  string(15) "(12) 88888-8888"
  [4]=>
  string(15) "(11) 97000-0333"
  [5]=>
  string(15) "(11) 98000-2222"
  [6]=>
  string(15) "(12) 99999-9999"
}

The idea is very simple, according to Wikipedia all Ddds have exactly 2 digits and start from 11, so we use:

substr($valor, 5);

So that we only get what is from the space, that is the first phone number from the phone (* actually it will get anything in the 5th character, no matter if it is a phone number or not*).

Then we use:

strtr($valor, ['-' => ''])

To remove the -, the use of strtr to the str_replace is only performance, it tends, in these cases, to be a little faster, in addition to personal preference even, but can use which prefer.

So we use the Spaceship Operator, read more here, it returns which value is higher, somewhat similar to the strcmp, but he just returns 1, 0 or -1.


If you want to list otherwise use the basic math of * (-1), this will cause 1 be it -1 and the same the contrary, thus ordering in a decreasing manner:

usort($telefones, function ($a, $b) {
    return (strtr(substr($a, 5), ['-' => '']) <=> strtr(substr($b, 5), ['-' => ''])) * (-1);
});

Regarding the reply of @Bruno Rigolon this should be a little faster, compare this and this in your machine.

/!\ It will not bring the data, so it will "trust" any value, so if there is (aa) 123c5-abc3, which is not a valid number, it will have no different action.

Browser other questions tagged

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