根据名字和姓氏数组生成简短的唯一用户名

发布于 2024-11-05 12:52:01 字数 1008 浏览 5 评论 0原文

我有一个名为 users 的多维数组,其格式如下,我正在尝试创建一个脚本,该脚本将根据以下信息创建“用户名”:

$users = [
    ['first_name' => 'Bob', 'last_name' => 'Smith'],
    ['first_name' => 'Steve', 'last_name' => 'Little'],
    ['first_name' => 'Eric', 'last_name' => 'Fielder'],
    ['first_name' => 'Steve', 'last_name' => 'Richardson'],
    ['first_name' => 'Bob', 'last_name' => 'Sanders'],
    ['first_name' => 'Bob', 'last_name' => 'Sanders'],
    ['first_name' => 'Bob', 'last_name' => 'Smith'],
];

所需逻辑:

  • 如果它使用的名字没有重复仅名字作为用户名 (“埃里克”)。

  • 如果两个名字的名字首字母相同,但姓氏首字母不同,则会使用名字作为姓氏首字母(“Steve L.”和“Steve R. ”)。

  • 如果多个人都具有姓氏和姓氏首字母,则返回全名(“Bob Smith”和“Bob Sanders”)。

  • 最后,如果找到相同的确切名称,则会为每个名称附加一个数字,如下所示:“Bob Sanders (1)”和“Bob Sanders (2)” >”

”我希望这可以有效地完成,而不需要很多循环,但我一生都无法弄清楚。

I have a multi-dimensional array called users that is formatted like the following and I am trying to create a script that will create a "username" based on this information:

$users = [
    ['first_name' => 'Bob', 'last_name' => 'Smith'],
    ['first_name' => 'Steve', 'last_name' => 'Little'],
    ['first_name' => 'Eric', 'last_name' => 'Fielder'],
    ['first_name' => 'Steve', 'last_name' => 'Richardson'],
    ['first_name' => 'Bob', 'last_name' => 'Sanders'],
    ['first_name' => 'Bob', 'last_name' => 'Sanders'],
    ['first_name' => 'Bob', 'last_name' => 'Smith'],
];

Required Logic:

  • If there are no duplicate first names it uses only the first name as the username
    ("Eric").

  • If there are two names with the same first but different initial letters in the last name it will use the first name as last initial ("Steve L." and "Steve R.").

  • If multiple people have the last first name and last initial then it return the full name ("Bob Smith" and "Bob Sanders").

  • Lastly, if the SAME exact name is found then it will append a number to each like this: "Bob Sanders (1)" and "Bob Sanders (2)"

I am hoping this can be done efficiently and not with a lot of loops, but I can not figure it out for the life of me.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

滥情空心 2024-11-12 12:52:01

这个脚本不是那么漂亮,但几乎可以满足您的要求。请注意,它仅使用两个循环,但需要一些额外的内存来存储有关用户的元数据:

    <?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>');
    ?>

This script is not that nifty but pretty much does what you want. Note that it only uses two loops but needs some additional memory to store meta data about the users:

    <?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>');
    ?>
睫毛溺水了 2024-11-12 12:52:01

我发现 Nayru 的代码片段太宽,难以理解,而且内存成本太高——为了方便查找,它存储了多余的计数。值得赞扬的是,它确实维护了行的顺序——如果这很重要的话。

另一种技术是将输入数据合并到嵌套组中(具有唯一的级别/键),然后迭代这些合并的级别并使用一系列条件来生成所需的用户名。这可能是跟踪名称冲突的最紧凑的方法。我当然觉得这是一段更容易维护和阅读的代码。

*如果您的姓氏可能以多字节字符开头,则应使用 mb_substr() 来隔离第一个字母
*此代码片段的结果不尊重输入的原始顺序,但如有必要,可以为此目的进行重构。
*它确实使用了多个循环,但这只是迭代嵌套级别的最有效方法——不要回避。

代码:(演示

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',
  ),
)

I find Nayru's snippet to be excessively wide, hard to follow, and too expensive in terms of memory -- it is storing redundant tallies for the sake of easy lookups. To its credit, it does maintain the order of the rows -- if that matters.

Another technique, is to consolidate the input data into nested groups (with unique levels/keys), then iterate those consolidated levels and use a battery of conditions to generate the desired usernames. This might be the most compact way to track the name collisions. I certainly feel that this is much easier piece of code to maintain and read.

*if your last names might start with a multibyte character, then mb_substr() shoul be used to isolate the first letter
*the result of this snippet does not respect the original order of the input, but it could be refactored for this purpose if necessary.
*it does use several loops, but this is just the most efficient means to iterating the nested levels -- not to be shied away from.

Code: (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);

Output:

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',
  ),
)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文