简体   繁体   English

Ruby中的数组和哈希迭代-Rails

[英]Array and Hash Iteration in Ruby - Rails

The params' hash keys are mix of camelcase, lowercase and uppercase characters: params的哈希键是驼峰,小写和大写字符的混合:

params = {"RefreshTime"=>"0", "lang"=>"tr", "amount"=>"50", "ACQBIN"=>"490740"}

The array , which is a list of one of my models' column names, is all lowercase but exactly the same values with the keys of params hash => 数组是我的一个模型列名称的列表,全部为小写字母,但与params键的值完全相同hash =>

columns = ["refreshtime", "lang", "amount", "acqbin", ......]

I'm trying to match hash keys with the members of the array to create a new record in my controller => 我试图将哈希键与数组的成员进行匹配,以在控制器中创建新记录=>

def create_transaction
   @transaction = OrderTransaction.new(
      params.each do |k, v|
        columns.each do |i|
          if i == k.downcase
            "#{i}: params[:#{k}],"
          end
        end
      end
    )
end

But this piece of code isn't working as I expected. 但是这段代码无法正常工作。 It seems like I'm doing something wrong in the line of; 看来我在做错事了;

#{i}: #{v}

What am I missing here? 我在这里想念什么?

By the way, this was my old way to do this job, which causes many lines of code => 顺便说一句,这是我执行此工作的旧方法,这导致很多行代码=>

@transaction = OrderTransaction.new(
  refreshtime: params[:RefreshTime],
  lang: params[:lang],
  amount: params[:amount],
  acqbin: params[:ACQBIN],
  ...
)

You could do something like this 你可以做这样的事情

@transaction = OrderTransaction.new(Hash[params.map{|k,v|[k.downcase,v]}])

This creates a new hash with all lowercase keys and uses it to initialize the OrderTransaction. 这将使用所有小写键创建一个新的哈希,并使用它来初始化OrderTransaction。

To only include keys that appear in the columns array 只包括出现在columns数组中的键

@transaction = OrderTransaction.new(Hash[params.map{|k,v|[k.downcase,v]}.select{|k,v|columns.include?(k)}])

You're not creating a hash entry, you're creating a string. 您不是在创建哈希条目,而是在创建字符串。

I'd suggest... 我建议...

eval "#{i}: params[:#{k}],"

Which hopefully will actually create the key value pair. 希望实际上会创建键值对。

or for that matter, why not... 还是为什么呢?

i.to_sym => params[k.to_sym]

I suggest a cleaner way to do it: 我建议一种更清洁的方法:

def create_transaction
    result_hash = {}
    params.each do |k,v|
        temp = k.to_s.downcase
        if columns.include? temp
            result_hash[temp] = v
        end
    end
    @transaction = OrderTransaction.new(result_hash)
end

Typically we'd create a mapping hash. 通常,我们会创建一个映射哈希。 Starting with: 从...开始:

params = {"RefreshTime"=>"0", "lang"=>"tr", "amount"=>"50", "ACQBIN"=>"490740"}

This is a fast way to do it if you know the maps are consistent: 如果您知道地图是一致的,这是一种快速的方法:

cols_to_key = Hash[params.keys.map(&:downcase).zip(params.keys)]
# => {"refreshtime"=>"RefreshTime",
#     "lang"=>"lang",
#     "amount"=>"amount",
#     "acqbin"=>"ACQBIN"}

Or: 要么:

cols_to_key = params.keys.map(&:downcase).zip(params.keys).to_h
# => {"refreshtime"=>"RefreshTime",
#     "lang"=>"lang",
#     "amount"=>"amount",
#     "acqbin"=>"ACQBIN"}

Accessing values looks like: 访问值如下所示:

params[cols_to_key['refreshtime']] # => "0"
params[cols_to_key['lang']] # => "tr"

You can even slice the params hash various ways. 您甚至可以通过多种方式对params切片。 If you want everything: 如果您想要一切:

params.values_at(*cols_to_key.values)
# => ["0", "tr", "50", "490740"]

If you want a few things: 如果您想要一些东西:

params.values_at(*cols_to_key.values_at('amount', 'acqbin'))
# => ["50", "490740"]

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

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