获取集合中对象的有效方式是通过其字段的值。

huangapple go评论43阅读模式
英文:

Efficient way to get an object from collection by value of one of its fields

问题

以下是翻译后的内容:

给定以下可能的输入之一该函数执行以下操作
 - ID数字字符串
 - 电子邮件@domain.tld结尾的字符串
 - 姓名由字母和数字组成的任何其他字符串

如果提供的内容不是 ID则它尝试通过将给定属性与用户对象列表中每个用户的相应字段进行比较来检索用户 ID所有这些用户对象都具有 ID 字段
例如如果提供了电子邮件它应该从用户列表中找到具有提供的电子邮件的用户然后返回此用户的 ID 字段的值
在 Django 中它会类似于这样:```User.objects.filter(email=input_string).first()```

在我的代码中以下行执行此操作
```user := next((user for user in users if user.email == input_string)```
它看起来不够优化且不够美观但我很难找到更简洁的解决方案
感谢任何关于此的建议

```python
def validate_user_id(input_string, users):
    if input_string.isdigit():
        return {'type': 'user', 'id': input_string}
    elif input_string.endswith(MAIL_DOMAIN):
        if user := next((user for user in users if user.email == input_string), None):
            return {'type': 'user', 'id': user.id}
        return None
    elif (input_string.isalnum() or
          ''.join(input_string.split('.')).isalnum()):
        if user := next((user for user in users if user.nickname == input_string), None):
            return {'type': 'user', 'id': user.id}
        return None
    raise ValueError(
        MEMBER_FORMAT_INVALID.format(identifier=input_string))
英文:

The following function is given one of the following possible inputs:

  • ID (numeric string)
  • email (string ending with @domain.tld)
  • name (any other alphanumeric string consisting)

If anything other than ID is given, it attempts to retrieve user ID by comparing a given attribute to the respective field of each user from a list of User objects, all of which have ID fields.
E.g., if an email is given, it should find a User from a list of Users that has the given email in its email field, then return value from this user's ID field.
In Django that would look like that User.objects.filter(email=input_string).first()

In my code, the following line is doing that:
user := next((user for user in users if user.email == input_string)
It looks suboptimal and ugly, but I'm struggling to find a neater solution.
Would appreciate any advice on that.

def validate_user_id(input_string, users):
    if input_string.isdigit():
        return {'type': 'user', 'id': input_string}
    elif input_string.endswith(MAIL_DOMAIN):
        if user := next((user for user in users if user.email == input_string), None):
            return {'type': 'user', 'id': user.id}
        return None
    elif (input_string.isalnum() or
          ''.join(input_string.split('.')).isalnum()):
        if user := next((user for user in users if user.nickname == input_string), None):
            return {'type': 'user', 'id': user.id}
        return None
    raise ValueError(
        MEMBER_FORMAT_INVALID.format(identifier=input_string))

答案1

得分: 1

为了使您的代码更加DRY和优化,可以使用以下方法:

  • 检查输入字符串格式以识别用户的目标属性
  • 不要从整个user对象中生成user.id,而是使用生成器表达式
def validate_user_id(input_str, users):
    if input_str.isdigit():  # 基本情况
        return {'type': 'user', 'id': input_str}

    if input_str.endswith(MAIL_DOMAIN):
        attr = 'email'
    elif (input_str.isalnum() or
          ''.join(input_str.split('.')).isalnum()):
        attr = 'nickname'
    else:
        raise ValueError(MEMBER_FORMAT_INVALID.format(identifier=input_str))

    user_id = next((user.id for user in users
                    if getattr(user, attr) == input_str), None)
    if user_id:
        return {'type': 'user', 'id': user_id}
    return None
英文:

To make your code more DRY and optimized use the following approach:

  • check the input string format to recognize the user's target attribute
  • instead of whole user object yield user.id from generator expression

def validate_user_id(input_str, users):
    if input_str.isdigit():  # base case
        return {'type': 'user', 'id': input_str}

    if input_str.endswith(MAIL_DOMAIN):
        attr = 'email'
    elif (input_str.isalnum() or
          ''.join(input_str.split('.')).isalnum()):
        attr = 'nickname'
    else:
        raise ValueError(MEMBER_FORMAT_INVALID.format(identifier=input_str))

    user_id = next((user.id for user in users
                    if getattr(user, attr) == input_str), None)
    if user_id:
        return {'type': 'user', 'id': user_id}
    return None

huangapple
  • 本文由 发表于 2023年2月24日 06:02:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/75550774.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定