2016-03-10 93 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"; 
}