【问题标题】:How to implement a search function for array of classes如何实现类数组的搜索功能
【发布时间】:2015-07-30 12:32:00
【问题描述】:

我有一个User 类如下:

class User
        attr_reader   :username, :password
        def inintialize(username, password)
                @username    = username
                @password    = password
        end
end

我想将其中许多 User 类存储在一个数组中,如下所示:

users = []

def initialize_users
        user = User.new("user0", "password0")
        users.push(user)

        user = User.new("user1", "password1")
        users.push(user)
end

现在我想实现一个搜索功能,我可以通过用户名或密码进行搜索。我知道我可以像这样遍历比较每个字段的类:

def search(username)
        users.each do |user|
                if user.username == username then
                        puts "Found"
                        break
                end
        end
end

但是有没有其他方法可以在没有迭代的情况下做到这一点,或者这只是最简单/最干净的方法?

我在想也许有办法做这样的事情:

users["username_to_find"]
=> true

虽然我不确定如何实现它。我相信我必须重写 User 类才能拥有一个内置列表,但从那里我迷路了。我想即使我确实实现了这个功能,仍然需要进行迭代。

我还想从该符号中访问该用户数据,例如

users["username_to_find"].password
=> "password111"

有人有什么想法吗?

PS:User 类被简化为相关代码,它实际上包含更多特定于每个用户的数据成员,例如套接字,以及用于将数据发送到特定用户套接字的方法

【问题讨论】:

  • 欢迎来到 Stack Overflow。创建标题时,请不要随意将“ruby”或您选择作为标签的类似词添加到句子的开头或结尾。改用正常的句子。 Stack Overflow 使用我们在搜索时定义的标签,并将它们提供给搜索引擎。如果你能将它们加入到句子的正常流程中,那很酷,但不要人为地添加它们。

标签: arrays ruby class


【解决方案1】:

您真的别无选择,只能遍历数组的每个元素并执行匹配测试。 Enumberable#detect 是您想要使用的:

def search(username)
  # return the first matching result
  users.detect { |user| user.username == username }
end

这将返回第一个具有匹配用户名的Usernil。如果您希望允许返回多个结果(例如,“搜索”一词表示的更多内容)而不是您希望使用返回所有匹配块的Enumberable#select

def search(username)
  # return ALL matching results
  users.select { |user| user.username == username }
end

如果您可能需要匹配多个条件(例如搜索用户名和名字等),则需要采用这种方法。如果您搜索用户名,那么上面@dax 给出的解决方案是完美的。

【讨论】:

    【解决方案2】:

    使用数组findselect 方法。假设您正在按名称搜索

    1. find 返回第一个满足您条件的对象

    array.find { |user| user.name == searched_name } # will be either one User or nil, if neither has name eq to searched_name

    1. select 返回所有满足你条件的对象

    array.select { |user| user.name == searched_name } #will be either array of Users which have name eq searched_name or an empty array when none has this name

    【讨论】:

    • 这仍然遍历数组吗?如果大概我有一个大型用户数据库,那么这需要多长时间而不是通过 hash['username'] 表示法搜索哈希?
    • hash['username'] 会更快。如果您在数据库中有用户,也许您应该按名称进行正确的数据库查询,以便只返回这些用户?如果要使用散列,请记住首先必须将用户数组映射到散列结构。这很容易,但也需要一些时间。在你的情况下,这将是:array.inject({}) { |memo, user| memo[user.username] = user; memo }
    【解决方案3】:

    如果它不需要是一个数组,为什么不使用哈希呢?它提供了您想要的功能。

    users = {}
    user = User.new("user0", "password0")
    users[user.username] = user
    

    像这样访问它

    users['tim_the_toolman'] # => nil, there is no user by that name
    users['user0'] # => returns user0
    users['user0'].password # => 'password0'
    

    【讨论】:

    • 与通过 djaszczurowski 提到的方法迭代数组相比,哈希查找的速度有多快?我可能会重新设计我的项目以足够轻松地使用哈希,而不是将方法内置到 User 类中。
    猜你喜欢
    • 2021-01-08
    • 2022-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-18
    相关资源
    最近更新 更多