Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 比较两个哈希值,不管是符号还是字符串,rails_Ruby On Rails_Ruby_Hash_Resque_String To Symbol - Fatal编程技术网

Ruby on rails 比较两个哈希值,不管是符号还是字符串,rails

Ruby on rails 比较两个哈希值,不管是符号还是字符串,rails,ruby-on-rails,ruby,hash,resque,string-to-symbol,Ruby On Rails,Ruby,Hash,Resque,String To Symbol,我想比较两个散列和力,使它们相等: 一个在键和值上带有符号 第二个只有字符串 e、 g: 这样做不行: > sym_hash == string_hash => false 我首先尝试用符号化字符串\u hash: > string_hash.deep_symbolize_keys => {:id=>58, :locale=>"en-US"} > sym_hash.with_indifferent_access => {"id"=>5

我想比较两个散列和力,使它们相等:

  • 一个在键值上带有符号
  • 第二个只有字符串
e、 g:

这样做不行:

> sym_hash == string_hash
=> false
我首先尝试用符号化
字符串\u hash

> string_hash.deep_symbolize_keys
=> {:id=>58, :locale=>"en-US"}
> sym_hash.with_indifferent_access
=> {"id"=>58, "locale"=>:"en-US"}
但是它仍然是错误的,因为
sym_hash
仍然在
区域设置
变量前面有

然后我尝试将
sym\u散列字符串化:

> string_hash.deep_symbolize_keys
=> {:id=>58, :locale=>"en-US"}
> sym_hash.with_indifferent_access
=> {"id"=>58, "locale"=>:"en-US"}
但当我测试是否相等时,出于同样的原因,它仍然是
false

编辑

为了回答关于为什么我希望这些散列在这里相等的许多评论,我将解释我正在尝试做什么

我用它来管理我的工作。现在,我想做一个类,以避免运行相同的*作业,或同时排队两次

(相同:对于我来说,相同的作业是具有相同参数的作业,例如,我希望能够两次enqueu具有不同ID的相同作业。)

因此,我是一个使用插件的用户,到目前为止,我能够知道作业何时运行。此外,当我使用
set
保存参数时,我注意到写入
Redis
的消息(因为resque status使用Redis跟踪作业的状态)没有用符号正确保存

这是我的班级:

# This class is used to run thread-lock jobs with Resque.
#
# It will check if the job with the exact same params is already running or in the queue.
# If the job is not finished, it will returns false,
# otherwise, it will run and returns a the uuid of the job.
#
class JobLock
  def self.run(obj, params = {})
    # Get rid of completed jobs.
    Resque::Plugins::Status::Hash.clear_completed
    # Check if your job is currently running or is in the queue.
    if !detect_processing_job(obj, params)
      job_uuid = obj.create(params)
      Resque::Plugins::Status::Hash.set(job_uuid,
                                        job_name: obj.to_s,
                                        params: params)
      job_uuid
    else
      false
    end
  end

  def self.detect_processing_job(obj, params = {})
    Resque::Plugins::Status::Hash.statuses.detect do |job|
      job['job_name'] == obj.to_s && compare_hashes(job['params'], params)
    end
  end

  def self.compare_hashes(string_hash, sym_hash)
    [sym_hash, string_hash].map do |h|
      h.map { |kv| kv.map(&:to_s) }.sort
    end.reduce :==
  end
end 
下面是我如何使用它:

JobLock.run(MyAwesomeJob, id: 58, locale: :"en-US")

正如你所看到的,我使用了@mudasobwa的答案,但我希望有一个更简单的方法来实现我正在尝试的目标

以下版本用作PHP强制平等:

[sym_hash, string_hash].map do |h|
  h.map { |kv| kv.map(&:to_s) }.sort
end.reduce :==
顺便说一句,这不仅仅是因为我尊重有智能手机的人。在宽度为80的端子上,这是一个完美的单线

要仅将符号强制为字符串,保留要与其字符串表示形式区分的数字,请执行以下操作:

[sym_hash, string_hash].map do |h|
  h.map { |kv| kv.map { |e| e.is_a?(Symbol) ? e.to_s : e } }.sort
end.reduce :==

以下版本用作PHP强制相等:

[sym_hash, string_hash].map do |h|
  h.map { |kv| kv.map(&:to_s) }.sort
end.reduce :==
顺便说一句,这不仅仅是因为我尊重有智能手机的人。在宽度为80的端子上,这是一个完美的单线

要仅将符号强制为字符串,保留要与其字符串表示形式区分的数字,请执行以下操作:

[sym_hash, string_hash].map do |h|
  h.map { |kv| kv.map { |e| e.is_a?(Symbol) ? e.to_s : e } }.sort
end.reduce :==

sym\u hash
中的
locale
值是一个符号
:“en-US”
, 而
string\u hash
中的
locale
的值是字符串。 所以他们是不平等的

现在如果你这样做了:

sym_hash = {:id=>58, :locale=>"en-US"}
string_hash = {"id"=>58, "locale"=>"en-US"}
string_hash.symbolize_keys!
sym_hash == string_hash
=> true

sym\u hash
中的
locale
值是一个符号
:“en-US”
, 而
string\u hash
中的
locale
的值是字符串。 所以他们是不平等的

现在如果你这样做了:

sym_hash = {:id=>58, :locale=>"en-US"}
string_hash = {"id"=>58, "locale"=>"en-US"}
string_hash.symbolize_keys!
sym_hash == string_hash
=> true

您可以尝试将这两个哈希转换为JSON,然后比较它们:

require 'json'
# => true 
sym_hash = {:id=>58, :locale=>:"en-US"}
# => {:id=>58, :locale=>:"en-US"} 
string_hash = {"id"=>58, "locale"=>"en-US"}
# => {"id"=>58, "locale"=>"en-US"} 
sym_hash.to_json == string_hash.to_json
# => true 

您可以尝试将这两个哈希转换为JSON,然后比较它们:

require 'json'
# => true 
sym_hash = {:id=>58, :locale=>:"en-US"}
# => {:id=>58, :locale=>:"en-US"} 
string_hash = {"id"=>58, "locale"=>"en-US"}
# => {"id"=>58, "locale"=>"en-US"} 
sym_hash.to_json == string_hash.to_json
# => true 
这个怎么样

require 'set'

def sorta_equal?(sym_hash, str_hash)
  return false unless sym_hash.size == str_hash.size
  sym_hash.to_a.to_set == str_hash.map { |pair|
    pair.map { |o| o.is_a?(String) ? o.to_sym : o } }.to_set
end

sym_hash= {:id=>58, :locale=>:"en-US"}

sorta_equal?(sym_hash, {"id"=>58, "locale"=>"en-US"})           #=> true 
sorta_equal?(sym_hash, {"locale"=>"en-US", "id"=>58 })          #=> true 
sorta_equal?(sym_hash, {"id"=>58, "local"=>"en-US", "a"=>"b" }) #=> false 
sorta_equal?(sym_hash, {"id"=>58, "lacole"=>"en-US"})           #=> false 
sorta_equal?(sym_hash, {"id"=>58, [1,2,3]=>"en-US"})            #=> false 
sorta_equal?({}, {})                                            #=> true 

class A; end
a = A.new
sorta_equal?({:id=>a, :local=>:b}, {"id"=>a, "local"=>"b"})     #=> true 
这个怎么样

require 'set'

def sorta_equal?(sym_hash, str_hash)
  return false unless sym_hash.size == str_hash.size
  sym_hash.to_a.to_set == str_hash.map { |pair|
    pair.map { |o| o.is_a?(String) ? o.to_sym : o } }.to_set
end

sym_hash= {:id=>58, :locale=>:"en-US"}

sorta_equal?(sym_hash, {"id"=>58, "locale"=>"en-US"})           #=> true 
sorta_equal?(sym_hash, {"locale"=>"en-US", "id"=>58 })          #=> true 
sorta_equal?(sym_hash, {"id"=>58, "local"=>"en-US", "a"=>"b" }) #=> false 
sorta_equal?(sym_hash, {"id"=>58, "lacole"=>"en-US"})           #=> false 
sorta_equal?(sym_hash, {"id"=>58, [1,2,3]=>"en-US"})            #=> false 
sorta_equal?({}, {})                                            #=> true 

class A; end
a = A.new
sorta_equal?({:id=>a, :local=>:b}, {"id"=>a, "local"=>"b"})     #=> true 

最后,为了回答我的问题,我不需要强制在散列之间进行比较。我使用
Marshal
来避免问题

class JobLock
  def self.run(obj, params = {})
    # Get rid of completed jobs.
    Resque::Plugins::Status::Hash.clear_completed
    # Check if your job is currently running or is in the queue.
    if !detect_processing_job(obj, params)
      job_uuid = obj.create(params)
      Resque::Plugins::Status::Hash.set(job_uuid,
                                        job_name: obj.to_s,
                                        params: Marshal.dump(params))
      job_uuid
    else
      false
    end
  end

  def self.detect_processing_job(obj, params = {})
    Resque::Plugins::Status::Hash.statuses.detect do |job|
      job['job_name'] == obj.to_s && Marshal.load(job['params']) == params
    end
  end
end 

不管怎样,我把这个问题放在这里,因为它可能会在将来帮助一些人…

最后,为了回答我的问题,我不需要强制在散列之间进行比较。我使用
Marshal
来避免问题

class JobLock
  def self.run(obj, params = {})
    # Get rid of completed jobs.
    Resque::Plugins::Status::Hash.clear_completed
    # Check if your job is currently running or is in the queue.
    if !detect_processing_job(obj, params)
      job_uuid = obj.create(params)
      Resque::Plugins::Status::Hash.set(job_uuid,
                                        job_name: obj.to_s,
                                        params: Marshal.dump(params))
      job_uuid
    else
      false
    end
  end

  def self.detect_processing_job(obj, params = {})
    Resque::Plugins::Status::Hash.statuses.detect do |job|
      job['job_name'] == obj.to_s && Marshal.load(job['params']) == params
    end
  end
end 

无论如何,我把这个问题放在这里,因为它可能会在将来帮助一些人…

这些散列是不同的,在这种情况下,我想修改它们以使它们相似。它不是一个线性函数(除非你用一个方法包装它),但是你可以循环散列,并根据它们的
方法将值与
方法进行比较。如果你愿意,我可以提供一个代码示例。我想要一个也可以比较空哈希的通用方法。所以我不想在每个散列上循环。但是请试一试!1.从您的示例中可以看出,对于一个散列(
sym\u hash
),键都是符号,没有值是字符串,而对于另一个散列(
string\u hash
),所有键都是字符串,没有值是符号。对的(那和你说的不一样。如果
string\u hash
中作为字符串的所有键和值都转换为符号,则需要知道这两个哈希是否相等。对的3.请澄清“强制它们相等”是什么意思。这些散列是不同的,在这种情况下,我想修改它们以使它们相似。它不是一条直线(除非用方法包装),但您可以循环散列,并根据它们的
与\u s
方法比较值。如果你愿意,我可以提供一个代码示例。我想要一个也可以比较空哈希的通用方法。所以我不想在每个散列上循环。但是请试一试!1.从您的示例中可以看出,对于一个散列(
sym\u hash
),键都是符号,没有值是字符串,而对于另一个散列(
string\u hash
),所有键都是字符串,没有值是符号。对的(那和你说的不一样。如果
string\u hash
中作为字符串的所有键和值都转换为符号,则需要知道这两个哈希是否相等。对的3.请澄清你所说的“强迫他们平等”是什么意思。泰,是的,我不管怎样都不在乎一句台词。所以它不存在一种自动转换sym哈希键和值的方法?我希望它不存在。你希望吗?为什么?我这里的问题是,我将第一个散列放入reddis缓存,但ofc reddis不处理符号参数。也许我的问题更多的是XY问题,我希望是因为Rails扩展基本上扼杀了自己编写代码的能力。Redis可以完美地处理AFAICT符号。如果
sym_hash
的值未定义,则#1也不起作用。我建议#1↷泰,是的,反正我不在乎一条客轮。所以它不存在一种自动转换sym哈希键和值的方法?我希望它不存在。你希望吗?为什么?我这里的问题是,我将第一个散列放入reddis缓存,但ofc reddis不手动