可枚举#rej_all,异常Ruby

时间:2016-06-28 22:39:24

标签: ruby

我试图在数组中查找所有负数,不包括某些类别中的对象。这是一个数组样本。

@transactions =
  [{"amount"=>-20, "name"=>"DEPOSIT", "category"=>["BENEFITS"], "category_id"=>"21007000"},
   {"amount"=>-0.8, "name"=>"XFER", "category"=>["Transfer", "Credit"], "category_id"=>"2106381"},
   {"amount"=>-20, "name"=>"DEPOSIT", "category"=>["Transfer", "Deposit"],
"category_id"=>"21007000"},
   {"amount"=>-1, "name"=>"XFER", "category"=>["Transfer", "Credit"],
"category_id"=>"21005000"},
   {"amount"=>300.80, "name"=>"XFER", "category"=>"Food", "category_id"=>"2106381"}]

到目前为止,我有类似的东西,但语法错误,它不起作用。我甚至不确定我是否可以使用"条件"在find_all块上。

items = @transactions.find_all ( { |t| t.fetch('amount') != t.fetch('amount').abs, :conditions => [ t.fetch('category_id') == '2106381' || t.fetch('category') == ["Benefits"] != ?, any? ]})

因此,找到金额为负数的所有对象,并从该列表中排除具有以下类别ID或类别名称的对象。

输出只有负数的对象,并且没有名称或类别ID的好处" 2106381"

4 个答案:

答案 0 :(得分:4)

您的问题并不是特别清楚,但我怀疑这样做符合您的要求:

@transactions.select do |t|
  t["amount"] < 0 &&
    t["category_id"] != "2106381" &&
    t["category"] != "Benefits"
end

或者,这更具说明性(但效率稍低):

@transactions.select {|t| t["amount"] < 0 }
  .reject {|t| t["category_id"] == "2106381" || t["category"] == "Benefits" }

答案 1 :(得分:2)

关于你在这里想要完成的事情仍然有点不清楚,但根据我的理解你想要:

1)包含所有负面amount的交易 2)排除指定category_id的所有交易 3)排除具有特定category

的所有交易

为此,您可以执行以下操作:

@transactions.find_all do |t|
  t['amount'] < 0 &&
  t['category_id'] != '2106381' &&
  t['category'] != ["BENEFITS"]
end

答案 2 :(得分:1)

以下解决方案为"amount"提供了三种不同的方案,并将"categories"格式设置为小写。

require 'pp' # require pretty_print

@transactions = [
  {"amount"=>-20, "name"=>"DEPOSIT", "category"=> ["BENEFITS"],"category_id"=>"21007000"},
  {"amount"=>-0.8, "name"=>"XFER", "category"=>["Transfer", "Credit"], "category_id"=>"2106381"},
  {"amount"=>-20, "name"=>"DEPOSIT", "category"=>["Transfer", "Deposit"], "category_id"=>"21007000"},
  {"amount"=>-1, "name"=>"XFER", "category"=>["Transfer", "Credit"], "category_id"=>"21005000"},
  {"amount"=>300.80, "name"=>"XFER", "category"=>"Food", "category_id"=>"2106381"}
]

# Enumerable#find_all
# see: http://ruby-doc.org/core-2.2.3/Enumerable.html#method-i-find_all
items = @transactions.find_all do |t|

  # 1) amount is less than zero
  t.fetch('amount') < 0 && 

  # 2) amount is less than zero or zero
  #t.fetch('amount') <= 0 && 

  # 3) Ruby 2.3 use core method: Numeric#negative?
  # see: http://ruby-doc.org/core-2.3.0/Numeric.html#method-i-negative-3F
  # see: https://github.com/ruby/ruby/blob/3a48e12/numeric.c#L4196-L4197
  # via: http://stackoverflow.com/a/34146626
  #t.fetch('amount').negative? &&

  t.fetch('category_id') != '2106381' &&

  # category is array so map and downcase before Array#include?
  # see: http://ruby-doc.org/core-2.2.3/Array.html#method-i-map
  # see: http://ruby-doc.org/core-2.2.3/Array.html#method-i-include-3F
  !(t.fetch('category').map {|c| c.downcase}.include?("benefits"))
end

pp items
# [{"amount"=>-20,
#  "name"=>"DEPOSIT",
#  "category"=>["Transfer", "Deposit"],
#  "category_id"=>"21007000"},
# {"amount"=>-1,
#  "name"=>"XFER",
#  "category"=>["Transfer", "Credit"],
#  "category_id"=>"21005000"}]

答案 3 :(得分:0)

我相信这会解决问题:

negative_transactions = @transactions.find_all do |trans| 
  trans["amount"] < 0 && (trans["category"] != ["BENEFITS"] && trans["category_id"] != "2106381")
end

puts negative_transactions