简体   繁体   中英

How to declare a multidimensional array with keys in ruby

The problem is that I have these parameters:

Parameters: {"multi_fees_transaction"=>{"amount"=>"20.00", "student_id"=>"5", "transaction_date"=>"2015-08-10", "payment_note"=>"", "payment_mode"=>"Cash"},
  "transactions"=>{"2"=>{"amount"=>"10", "finance_id"=>"4", "payee_id"=>"5", "category_id"=>"14", "payee_type"=>"Student", "transaction_date"=>"2015-08-10", "title"=>"Receipt No.. (Multiple Fees) F4", "finance_type"=>"FinanceFee", "payment_mode"=>"Cash", "payment_note"=>""}, 
        "1"=>{"amount"=>"10", "finance_id"=>"4", "payee_id"=>"2", "category_id"=>"14", "payee_type"=>"Student", "transaction_date"=>"2015-08-10", "title"=>"Receipt No.. (Multiple Fees) F4", "finance_type"=>"FinanceFee", "payment_mode"=>"Cash", "payment_note"=>""}}, 
        "controller"=>"parent_wise_fee_payments", "authenticity_token"=>"tvgD1IXP14h1dtsAjgqaS5o5reRXTPzjCPRVrwPc9Vg=", "transaction_date"=>"2015-08-10", "action"=>"pay_all_fees"}

And I need to create something like this:

 params[:transactions].each do |trans|
        multi_fees["amount"]=trans["amount"]
        multi_fees["student_id"]=trans["payee_id"]
        multi_fees["transaction_date"]=trans["transaction_date"]
        multi_fees["payment_note"]=params[:multi_fees_transaction]["payment_note"]
        multi_fees["payment_mode"]=params[:multi_fees_transaction]["payment_mode"]
end

This is giving an error because I need to define multi_fees array. But I just couldn't find a way to do this. Could you please help me?

This can be done using Enumerable#map (a Hash is an Enumerable object):

multi_fees = params[:transactions].values.map do |trans|
  {
    "amount" => trans["amount"],
    "student_id" => trans["payee_id"],
    "transaction_date" => trans["transaction_date"],
    "payment_note" => trans["payment_note"],
    "payment_node" => trans["payment_node"],
  }
end

The block passed to #map gets called for each value in the params[:transactions] hash. The block's value is a hash. The hashes returned by all of the invocations of the block are concatenated into an array, which is assigned to multi_fees.

multi_fees = params['transactions'].values.map do |h|
  h.select { |k, _| # select from respective transaction 
    ['amount', 'payee_id', 'transaction_date'].include? k 
  }.merge params['multi_fees_transaction'].select { |k, _| # select globally
    ['payment_note', 'payment_mode'].include? k
  }
end

The idea is to union mapped results with globally selected:

#⇒ [
#  [0] {
#              "amount" => "10",
#            "payee_id" => "5",
#        "payment_mode" => "Cash",
#        "payment_note" => "",
#    "transaction_date" => "2015-08-10"
#  },
#  [1] {
#              "amount" => "10",
#            "payee_id" => "2",
#        "payment_mode" => "Cash",
#        "payment_note" => "",
#    "transaction_date" => "2015-08-10"
#  }
# ]

Also, be careful with the wording. multi_fees is not an array. It's a hash.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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