繁体   English   中英

在哈希内的数组中查找元素

[英]Finding an element in an array inside a hash

@members = {
            approved: ["Jill"],
            unapproved: ["Daniel"],
            removed: ["John"],
            banned: ["Daniel", "Jane"]
        }

很简单:制作一个程序来跟踪会员资格。 在上面的哈希中,您可以看到四个成员资格状态键,每个键都有一个包含名称的数组。

我正在尝试创建一个find_member方法,该方法允许用户输入名称,然后在每个数组中搜索该名称,并告诉用户该名称位于哪个键中。

我对哈希不是很好,在尝试执行此操作时,我创建了一个混乱的循环,并且我想有一个非常简单的解决方案,但到目前为止我还没有找到。 有没有很简单的方法可以做到这一点?

我已经尝试了一些事情,但仍然没有过去的所有努力,但这是我最后遇到的最新情况,可能比我以前做的还要糟:

def find_member
  puts "==Find Member=="
  puts "Name: "
  @name = gets.chomp
  @members.each do |key|
    key.values.each do |array|
      array.each do |element|
        if @name == element
          puts "#{@name} found in #{key}"
        else
          puts "#{@name} not found in #{key}"
        end
      end
    end
  end
end

谢谢。

您可以在include?使用此功能include? 方法。

@members = {
  approved: ["Jill"],
  unapproved: ["Daniel"],
  removed: ["John"],
  banned: ["Daniel", "Jane"]
}

def find_member_group(name)
  @members.each { |group, names| return group if names.include?(name) }
  nil
end

@name = 'Jane'

group_name = find_member_group(@name)
puts group_name ? "#{@name} found in #{group_name}." : "#{@name} not found."
# => Jane found in banned.

Hash#select是在此处使用的方法:

def find_member(name)
  @members.select {|k,v| v.include? name }.keys
end

find_member("Jill")   #=> [:approved]
find_member("Daniel") #=> [:unapproved, :banned]
find_member("John")   #=> [:removed]
find_member("Jane")   #=> [:banned]

说明:

select顾名思义,仅选择映射满足相应代码块中条件的那些元素。 该代码块不需要if语句。 在代码块中,我们检查每个键值对 ,如果其 包含 name参数,则将选择该键值对并将其映射到最终输出。 最后,我们只对成员资格(即键)感兴趣,因此我们应用keys方法以数组的形式获取这些成员资格。

最有效的方法是创建名称到键的一对多映射,并仅在@members更改时更新该映射。

def find_member(name)
  update_names_to_keys_if_necessary
  @member_to_keys[name]
end

def update_names_to_keys_if_necessary
  new_hashcode = @members.hash  
  return if @old_members.hashcode == new_hashcode
  @member_to_keys = @members.each_with_object(Hash.new { |h,k| h[k] = [] }) { |(k,v),h|
    v.each { |name| h[name] << k } }
  @old_members_hashcode = new_hashcode
end

需要注意的是@old_members_hashcode计算结果为nil首次update_names_to_keys_if_necessary被调用,所以@member_to_keys将在那个时候被创建。

最初我们获得

@member_to_keys
  #=> {"Jill"=>[:approved], "Daniel"=>[:unapproved, :banned],
  #    "John"=>[:removed], "Jane"=>[:banned]} 

试试吧。

find_member("Jill")
  #=> [:approved] 
find_member("Daniel")
  #=> [:unapproved, :banned] 
find_member("John")
  #=> [:removed] 
find_member("Jane")
  #=> [:banned] 
find_member("Billy-Bob")
  #=> [] 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM