Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sort an array with PHP, ignoring the articles (a, an, the) in the beginning?

Suppose I have the following array $books (the actual array is much larger):

Array
(
    [0] => The Mystic Masseur
    [1] => The Suffrage of Elvira
    [2] => Miguel Street
    [3] => A House for Mr Biswas
    [4] => Mr Stone and the Knights Companion
    [5] => The Mimic Men
    [6] => A Flag on the Island
    [7] => In a Free State
    [8] => Guerrillas
    [9] => A Bend in the River
    [10] => The Enigma of Arrival
    [11] => A Way in the World
    [12] => Half a Life
    [13] => Magic Seeds
)

When I use the sort function, the result is this:

Array
(
    [0] => A Bend in the River
    [1] => A Flag on the Island
    [2] => A House for Mr Biswas
    [3] => A Way in the World
    [4] => Guerrillas
    [5] => Half a Life
    [6] => In a Free State
    [7] => Magic Seeds
    [8] => Miguel Street
    [9] => Mr Stone and the Knights Companion
    [10] => The Enigma of Arrival
    [11] => The Mimic Men
    [12] => The Mystic Masseur
    [13] => The Suffrage of Elvira
)

But I would like to ignore the articles (a, an, the) in the beginning and would like to have a result like this:

Array
(
    [0] => A Bend in the River
    [1] => The Enigma of Arrival
    [2] => A Flag on the Island
    [3] => Guerrillas
    [4] => Half a Life
    [5] => A House for Mr Biswas
    [6] => In a Free State
    [7] => Magic Seeds
    [8] => Miguel Street
    [9] => The Mimic Men
    [10] => Mr Stone and the Knights Companion
    [11] => The Mystic Masseur
    [12] => The Suffrage of Elvira
    [13] => A Way in the World
)

I’ve tried:

$_books = array();
foreach($books as $book){
    if(substr($book, 0, 4) == "The "){
    $_books[substr($book, 4)] = $book;
    }
    else if(substr($book, 0, 3) == "An "){
    $_books[substr($book, 3)] = $book;
    }
    else if(substr($book, 0, 2) == "A "){
    $_books[substr($book, 2)] = $book;
    }
    else{
    $_books[$book] = $book;
    }
}
ksort($_books);
$books = array_values($_books);

But I know this is not the best solution because it has the risk of losing values (e.g. if there are both “A Fantasy” and “The Fantasy” in the input, there will be only “The Fantasy” in the output). So, what is the best solution?

like image 363
Soumalyo Bardhan Avatar asked Dec 23 '13 13:12

Soumalyo Bardhan


People also ask

How can we sort an array without using sort method in PHP?

php function sortArray() { $inputArray = array(8, 2, 7, 4, 5); $outArray = array(); for($x=1; $x<=100; $x++) { if (in_array($x, $inputArray)) { array_push($outArray, $x); } } return $outArray; } $sortArray = sortArray(); foreach ($sortArray as $value) { echo $value . "<br />"; } ?>

How do you sort an array by a specific value in PHP?

PHP - Sort Functions For Arraysrsort() - sort arrays in descending order. asort() - sort associative arrays in ascending order, according to the value. ksort() - sort associative arrays in ascending order, according to the key. arsort() - sort associative arrays in descending order, according to the value.

How do you sort an array of objects in PHP?

The usort() function is an inbuilt function in PHP which is used to sort the array of elements conditionally with a given comparator function. The usort() function can also be used to sort an array of objects by object field.

Do PHP arrays start at 0 or 1?

PHP lets you create 2 types of array: Indexed arrays have numeric indices. Typically the indices in an indexed array start from zero, so the first element has an index of 0 , the second has an index of 1 , and so on.


2 Answers

Use a custom sort function:

function handleArticles($str) {
    list($first,$rest) = explode(" ",$str." ",2);
       // the extra space is to prevent "undefined offset" notices
       // on single-word titles
    $validarticles = array("a","an","the");
    if( in_array(strtolower($first),$validarticles)) return $rest.", ".$first;
    return $str;
}
usort($books,function($a,$b) {
    return strnatcasecmp(handleArticles($a),handleArticles($b));
});
like image 134
Niet the Dark Absol Avatar answered Nov 08 '22 23:11

Niet the Dark Absol


Edited. Use custom function like this:

function customSort($a, $b) {
    $list = array(
        'The' => '',
        'A' => '',
    );
    $pattens = array();
    $replacement = array();
    foreach ($list as $from => $to){
        $from = '/\b' . $from . '\b/';
        $pattens[] = $from;
        $replacement[] = $to;
    }
     $a = preg_replace($pattens, $replacement, $a);
     $b = preg_replace($pattens, $replacement, $b);

     return strcmp($a,$b);
}
       $array = array("The Vendor", "The World of War", "A World of War");
       usort($array, 'customSort');

    print_r($array);

Result:

Array ( [0] => The Vendor [1] => A World of War [2] => The World of War ) 
like image 31
sergio Avatar answered Nov 08 '22 23:11

sergio