Sort an array by specific letter

0

I used asort to order an associative arrangement of words for a search box, I opted for it to avoid changing the order of the keys, the problem is that when making the search the first letter entered by the user should appear Among the first positions, an example:

Here the search is done starting with the letter to and adding words that contain to alphabetical order.

Here the search does NOT show the results by the first letter (in this case j ), but it shows the order starting with a and that contains a j :

How could I order an arrangement by starting with a specific letter?

Here the code used:

# datos obtenidos por BD
$datos = array("1"=>"java","2"=>"android","3"=>"ajax","4"=>"asp.net","5"=>"javascript");
$res = array();
$q = $_REQUEST["q"];
if ($q !== "") {
    asort($datos); //ordenado por valor
    foreach($datos as $key => $value) {
        if (stristr($value,$q)) {
            if (count($res) < 5) { //limitar la busqueda a 5
                array_push($res,array('id'=>$key,'nombre'=>'#'.ucwords($value)));
            }               
        }

    }
}
echo count($res) === 0 ? show_404() : json_encode($res);
    
asked by iuninefrendor 06.02.2018 в 00:13
source

2 answers

2

When you run asort at the beginning of the loop, your array is sorted for everything that follows. What you need is to reorder it after having filtered those that fit the criteria. For example, you can use usort to define the order criteria yourself:

usort expects a function that receives two elements $a and $b and compares them according to a criterion that you define. Returns 1 if $a > $b , 0 if they are equal and -1 if $a < $b .

In this case your function could be:

usort($res, function($a, $b) use ($q) {
    $pos1 = stripos($a['nombre'],$q);
    $pos2 = stripos($b['nombre'],$q);
    if($pos1 === $pos2) {
      return 0; 
    }
    return ($pos1 > $pos2) ? 1 : -1;
});

(see example fiddle)

Within that function I am saying: the position of $q in the name chain determines if one element must go before the other. But you can spin finer and make, for example, if the position is the same in both elements, order these alphabetically.

    
answered by 06.02.2018 / 01:59
source
0

I think this function can help you. Here all the elements of the array are sorted, starting with the last letter in parameter. Then the other elements would follow in alphabetical order.

The possibility of uppercase letters is also contemplated, both in the values of the array, and in the written letter that would be used as a search criterion.

In theory, the function does the following:

  • Sort the original array alphabetically with natcasesort
  • Convert the last letter to lowercase using strtolower , that way it will not fail if you pass uppercase letters to it.
  • Do the same procedure with each value.
  • Use strpos to verify if the value starts with the letter passed in parameter. If so, enter the current element in a new array $arrInicial and remove it from the original array with unset .
  • At the end, create a new $arrFinal , composed of $arrInicial (where the found values will be) and $arrOrigen (where the values that were not found will be).
  • I hope it serves you.

    Function code

    VIEW DEMO IN REXTESTER

    /*Función*/
    function orderArrayByChar($arrOrigen, $letra)
    {
        natcasesort($arrOrigen);
        $arrInicial=array();
        $letra=strtolower($letra);
    
        if (count($arrOrigen) > 0) {
            foreach ($arrOrigen as $k => $v) {
                $elValor=strtolower($v);
                $siLetra = strpos($elValor, $letra) === 0;
                if ($siLetra){
                    $arrInicial[$k]=$v;
                    unset($arrOrigen[$k]);
                }
            }
            $arrFinal = $arrInicial+ $arrOrigen;
        }
        return $arrFinal;
    }
    

    Test code

    /*Pruebas*/
    echo "Array original:".PHP_EOL.PHP_EOL;
    $arrDatos = array("1"=>"javax","2"=>"android","3"=>"ajax","4"=>"asp.net","5"=>"javascript","6"=>"phyton","7"=>"PHP");
    print_r($arrDatos);
    
    echo PHP_EOL.PHP_EOL."Prueba con j".PHP_EOL.PHP_EOL;
    $q = 'j';//$_REQUEST["q"];
    natcasesort($arrDatos);
    $arrOrdenado=orderArrayByChar($arrDatos, $q);
    print_r($arrOrdenado);
    
    
    /*Importante usar natcasesort, si no dará problemas con las mayúsculas*/
    echo PHP_EOL.PHP_EOL."Prueba con p".PHP_EOL.PHP_EOL;
    
    $q = 'P';//$_REQUEST["q"];
    $arrDatos = array("1"=>"javax","2"=>"android","3"=>"ajax","4"=>"asp.net","5"=>"javascript","6"=>"phyton","7"=>"PHP");
    natcasesort($arrDatos);
    $arrOrdenado=orderArrayByChar($arrDatos, $q);
    print_r($arrOrdenado);
    

    Result:

    Array original:
    
    Array
    (
        [1] => javax
        [2] => android
        [3] => ajax
        [4] => asp.net
        [5] => javascript
        [6] => phyton
        [7] => PHP
    )
    
    
    Prueba con j
    
    Array
    (
        [5] => javascript
        [1] => javax
        [3] => ajax
        [2] => android
        [4] => asp.net
        [7] => PHP
        [6] => phyton
    )
    
    
    Prueba con p
    
    Array
    (
        [7] => PHP
        [6] => phyton
        [3] => ajax
        [2] => android
        [4] => asp.net
        [5] => javascript
        [1] => javax
    )
    
        
    answered by 06.02.2018 в 03:27