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

Sou*_*han 8 php arrays sorting

假设我有以下数组$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
)
Run Code Online (Sandbox Code Playgroud)

当我使用该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
)
Run Code Online (Sandbox Code Playgroud)

但我想在开头忽略文章(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
)
Run Code Online (Sandbox Code Playgroud)

我试过了:

$_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);
Run Code Online (Sandbox Code Playgroud)

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

Nie*_*sol 14

使用自定义排序功能:

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));
});
Run Code Online (Sandbox Code Playgroud)

  • 总结这里发生的事情:重新组织数组中的每个条目,将初始文章移动到单词的末尾,用逗号分隔.例如:"世界之路"成为"世界之路,A".然后,这个新字符串是自定义排序函数的不区分大小写的字符串比较. (2认同)

ser*_*gio 6

编辑.使用这样的自定义函数:

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);
Run Code Online (Sandbox Code Playgroud)

结果:

Array ( [0] => The Vendor [1] => A World of War [2] => The World of War ) 
Run Code Online (Sandbox Code Playgroud)