2016-03-10 150 views
1

因此,我將名稱存儲在數據庫中,但它們作爲姓氏存儲在一個字段中。例如,字段名稱names顯示john doephp按姓氏排序刪除列表

我想讓我的name成爲姓氏第一,名字最後(例如:doe, john),所以我有這種想法(代碼如下),但在此之後,我需要按姓氏排序數組,我怎麼能做這個?

$names = array(
    1 => "Joe Johnson", 
    2 => "Ann Marie blah", 
    3 => "person three" 
); 

foreach ($names as $id => $name) { 

$parts = explode(" ", $name); 

$lastname = array_pop($parts); 

$firstname = implode(" ", $parts); 

$name = $lastname.", ".$firstname." "; 

echo  
    "<option value='$id'>$name</option>\n"; 
} 
+2

有人在那裏有幾個名字,中間名等。還有一些人擁有不止一個姓氏。這種情況發生在整個國家,習俗是將父母的姓氏作爲姓氏。你如何決定在不冒犯任何人的情況下,一個人可以用他們的名字命名的3-4-5個或更多的單詞有多少是給定的名字和多少個姓?不可能完成的任務。 – axiac

+0

@axiac優秀點。此外,有些人只有一個名字(不只是王子)。 –

回答

1

問題是,你在相同的foreach()循環中回顯名稱和姓氏。

只需很少的修改,您就可以獲得所需的結果。

首先,在foreach()環路(&$name之前)使用參考。通過這種方式,您將直接更改數組值,而不是它們的副本。 $id在此foreach中不是必需的。從這個循環中取出echo

foreach($names as &$name) 
{ 
    $parts  = explode(" ", $name); 
    $lastname = array_pop($parts); 
    $firstname = implode(" ", $parts); 
    $name  = $lastname.", ".$firstname." "; 
} 

foreach()循環的結束,我們必須unset()$name以獲得正確的結果(感謝先生不要驚慌進行諮詢。):

unset($name); 

然後,使用natcasesort()排序您的數組。隨着natcasesort,你的排序不區分大小寫,並保持原有的鑰匙,因此在你<option>id具有相同的原始數組:

natcasesort($names); 

最後,執行附加foreach()循環呼應名稱:

foreach($names as $id => $name) 
{ 
    echo "<option value='$id'>$name</option>\n"; 
} 

編輯:

如果你喜歡(我喜歡),可以完全替代第一foreach()循環使用array_walk()preg_replace()

array_walk 
(
    $names, 
    function(&$val) 
    { 
     $val = '['.preg_replace('/^(.+) +(\S+)$/','\2, \1',$val).']'; 
    } 
); 

我已經爆炸了清晰的語法,但它是一個代碼行。

+0

不要忘記在foreach之後取消參考。起初我忘了這件事,我得到了兩個約翰遜,喬,沒有三個人。 –

+0

@ Don'tPanic當然?我不。我會重新測試。感謝您的提示:) – fusion3k

+0

嗨@fusion,我不一定是指針對你的評論,只是供參考,因爲我們的答案是如此相似(儘管你的更徹底的解釋),我遇到了這個問題。 –

0

只得到了姓氏爲Array後,你應該使用asort()保存鍵關聯,這樣你就可以創建基於這些密鑰的新陣。

$names = array(
    1 => 'Joe Johnson', 
    2 => 'Ann Marie blah', 
    3 => 'person three' 
); 
function sortLastNames(&$fromArray){ 
    $s = $r = array(); 
    foreach($fromArray as $k => $v){ 
    $s[$k] = substr($v, (strrpos($v, ' ')+1)); 
    } 
    asort($s, SORT_NATURAL | SORT_FLAG_CASE); 
    foreach($s as $k => $v){ 
    $r[$k] = $fromArray[$k]; 
    } 
    $fromArray = $r; 
} 
sortLastNames($names); $opts = ''; 
foreach($names as $k => $v){ 
    $opts .= "<option value='$k'>$v</option>\n"; 
} 
$test = '<select>'.$opts.'</select>'; 
// now `echo $test;` where you want it 

請注意,&$fromArray表示您作爲參數傳遞的數組受到影響。這個函數不會返回一個新的Array。

0

你可以做你現在正在做的事情,但是使用一個引用,以便用新的姓氏優先格式更新數組,而不是在第一遍中回顯名稱。

foreach ($names as $id => &$name) { // use a reference here 
    $parts = explode(" ", $name); 
    $lastname = array_pop($parts); 
    $firstname = implode(" ", $parts); 
    $name = $lastname.", ".$firstname." "; 
} 

unset($name); // unset the reference 

sort($names, SORT_NATURAL | SORT_FLAG_CASE); // sort the array 

// then one more pass to echo the sorted names 
foreach ($names as $id => $name) { 
    echo "<option value='$id'>$name</option>\n"; 
}