如何使用PHP对数组进行排序,忽略文章(a,an,the)?

时间:2020-12-15 15:56:07

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

假设我有以下数组$ books(实际数组更大):

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:

当我使用sort函数时,结果如下:

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:

但我想在开头忽略文章(a,an,the),并希望得到这样的结果:

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?

但我知道这不是最好的解决方案,因为它有丢失价值的风险(例如,如果输入中同时存在“A Fantasy”和“The Fantasy”,则输出中只会出现“The Fantasy”)。那么,什么是最好的解决方案?

2 个解决方案

#1


14  

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));
});

#2


6  

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 ) 

#1


14  

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));
});

#2


6  

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 )