我有一个名为users的多维数组,格式如下,我正在尝试创建一个脚本,根据这些信息创建一个“用户名”:
$users(first_name => 'Bob', last_name => 'Smith')
$users(first_name => 'Steve', last_name => 'Little')
$users(first_name => 'Eric', last_name => 'Fielder')
$users(first_name => 'Steve', last_name => 'Richardson')
$users(first_name => 'Bob', last_name => 'Sanders')
$users(first_name => 'Bob', last_name => 'Sanders')
如果有的话 没有重复使用的名字 第一个名称作为用户名 ( “埃里克”)。
如果有两个名称相同 首先但不同的首字母 在姓氏中它将使用 名字作为最后一个首字母(“史蒂夫 L。“和” Steve R。“)。
如果有多人拥有最后一个 名字和最后一个首字母然后它 返回全名(“ Bob Smith ”和 “ Bob Sanders ”)。
最后,如果SAME确切名称是 发现它会附加一个数字 每个人都这样:“鲍勃桑德斯(1)”和 “ Bob Sanders(2)”
我希望这可以有效地完成,而不是通过很多循环,但我无法理解我的生活。
提前感谢您提供任何帮助!
答案 0 :(得分:1)
这个脚本不是那么漂亮,但几乎可以做你想要的。请注意,它只使用两个循环,但需要一些额外的内存来存储有关用户的元数据:
<?php
$users = array(
array("first_name"=>"Bob", "last_name"=>"Smith"),
array("first_name"=>"Steve", "last_name"=>"Little"),
array("first_name"=>"Eric", "last_name"=>"Fielder"),
array("first_name"=>"Steve", "last_name"=>"Richardson"),
array("first_name"=>"Bob", "last_name"=>"Sanders"),
array("first_name"=>"Bob", "last_name"=>"Sanders")
);
$_users_info = array("first_name_count"=>array(),"last_name_count"=>array(),"first_name_last_initial_count"=>array());
foreach($users as $user){
$_users_info["first_name_count"][$user["first_name"]] = isset($_users_info["first_name_count"][$user["first_name"]]) ? ++$_users_info["first_name_count"][$user["first_name"]] : 1;
$_users_info["last_name_count"][$user["last_name"]] = isset($_users_info["last_name_count"][$user["last_name"]]) ? ++$_users_info["last_name_count"][$user["last_name"]] : 1;
$_users_info["first_name_last_initial_count"][$user["first_name"]."#".substr($user["last_name"],0,1)] = isset($_users_info["first_name_last_initial_count"][$user["first_name"]."#".substr($user["last_name"],0,1)]) ? ++$_users_info["first_name_last_initial_count"][$user["first_name"]."#".substr($user["last_name"],0,1)] : 1;
$_users_info["complete_name_count"][$user["first_name"]."#".$user["last_name"]] = isset($_users_info["complete_name_count"][$user["first_name"]."#".$user["last_name"]]) ? ++$_users_info["complete_name_count"][$user["first_name"]."#".$user["last_name"]] : 1;
$_users_info["complete_name_allocated"][$user["first_name"]."#".$user["last_name"]] = 0;
}
print('<pre>');
foreach($users as $user) {
$username = null;
if($_users_info["first_name_count"][$user["first_name"]]==1) $username = $user["first_name"];
else if($_users_info["first_name_last_initial_count"][$user["first_name"]."#".substr($user["last_name"],0,1)]==1) $username = $user["first_name"]." ".substr($user["last_name"],0,1).".";
else if($_users_info["last_name_count"][$user["last_name"]]==1) $username = $user["first_name"]." ".$user["last_name"];
else $username = $user["first_name"]." ".$user["last_name"].sprintf(" (%d)",++$_users_info["complete_name_allocated"][$user["first_name"]."#".$user["last_name"]]);
printf("%s %s => %s\n",$user["first_name"],$user["last_name"],$username);
}
print('</pre>');
?>
答案 1 :(得分:0)
我发现 Nayru 的代码段过于宽泛、难以理解,而且在内存方面太昂贵——它为了便于查找而存储了冗余的记录。值得称赞的是,它确实维护了行的顺序——如果这很重要的话。
另一种技术是将输入数据合并到嵌套组中(具有唯一级别/键),然后迭代这些合并级别并使用一组条件来生成所需的用户名。这可能是跟踪名称冲突的最紧凑的方法。我当然觉得这是一段更容易维护和阅读的代码。
*如果您的姓氏可能以多字节字符开头,则应使用 mb_substr()
来隔离第一个字母
*此代码段的结果不尊重输入的原始顺序,但如有必要,可以为此目的对其进行重构。
*它确实使用了几个循环,但这只是迭代嵌套级别的最有效方法——不要回避。
代码:(Demo)
foreach ($users as $row) {
$grouped[$row['first_name']][$row['last_name'][0] ?? ''][$row['last_name']][] = $row;
}
$result = [];
foreach ($grouped as $firstName => $leadingLetterGroup) {
$leadingLetterCount = count($leadingLetterGroup);
foreach ($leadingLetterGroup as $leadingLetter => $lastNameGroup) {
$lastNameCount = count($lastNameGroup);
foreach ($lastNameGroup as $lastName => $rows) {
if (count($rows) === 1) {
if ($leadingLetterCount === 1) {
$username = $firstName;
} elseif ($lastNameCount === 1) {
$username = "$firstName $leadingLetter.";
} else {
$username = "$firstName $lastName";
}
$result[] = $rows[0] + ['username' => $username];
} else {
foreach ($rows as $i => $row) {
$username = sprintf("%s %s (%d)", $firstName, $lastName, $i + 1);
$result[] = $row + ['username' => $username];
}
}
}
}
}
var_export($result);
输出:
array (
0 =>
array (
'first_name' => 'Bob',
'last_name' => 'Smith',
'username' => 'Bob Smith (1)',
),
1 =>
array (
'first_name' => 'Bob',
'last_name' => 'Smith',
'username' => 'Bob Smith (2)',
),
2 =>
array (
'first_name' => 'Bob',
'last_name' => 'Sanders',
'username' => 'Bob Sanders (1)',
),
3 =>
array (
'first_name' => 'Bob',
'last_name' => 'Sanders',
'username' => 'Bob Sanders (2)',
),
4 =>
array (
'first_name' => 'Steve',
'last_name' => 'Little',
'username' => 'Steve L.',
),
5 =>
array (
'first_name' => 'Steve',
'last_name' => 'Richardson',
'username' => 'Steve R.',
),
6 =>
array (
'first_name' => 'Eric',
'last_name' => 'Fielder',
'username' => 'Eric',
),
)