【问题标题】:How to loop through arrays of different length in Ruby?如何在Ruby中遍历不同长度的数组?
【发布时间】:2016-04-25 16:27:28
【问题描述】:

假设我有两个用户日常买卖的关系数组。

我如何使用.each 遍历它们,并且在较短的数组用尽后仍然让较长的数组独立运行。下面我想找到某人每日买卖的比率。但无法获得比率,因为它始终为 1,因为我为较短数组的每个项目遍历较长的数组一次。

users = User.all
ratios = Hash.new

users.each do |user|

  if user.buys.count > 0 && user.sells.count > 0

    ratios[user.name] = Hash.new
    buy_array = []
    sell_array = []
    date = ""

    daily_buy = user.buys.group_by(&:created_at)
    daily_sell = user.sells.group_by(&:created_at)

    daily_buy.each do |buy|
      daily_sell.each do |sell|
        if buy[0].to_date == sell[0].to_date
          date = buy[0].to_date
          buy_array << buy[1]
          sell_array << sell[1]
        end
      end
    end
    ratio_hash[user.name][date] = (buy_array.length.round(2)/sell_array.length)
  end
end

谢谢!

【问题讨论】:

  • 我不明白你的问题。读者不必试图从代码中推断问题,尤其是从不起作用的代码中。考虑一下如何在不提供任何代码的情况下清楚地陈述问题。通常一个例子会有所帮助。当您给出示例时,为每个输入对象分配一个变量(例如,arr = [1,2,3])并显示该输入所需的输出。包含变量的原因是为了让读者可以在 cmets 和解决方案中剪切和粘贴并引用它们,而无需定义它们。
  • 另外,避免询问如何采用特定方法(例如,“我如何使用each 遍历它们?”),这样您就不会关闭其他方法,可能更好的方法。只需解释您想要实现的目标。我建议您编辑您的问题以至少添加一个示例。如果您这样做,请留下您所拥有的并将其添加到最后,表明它是一个编辑(例如“编辑:....”)。
  • 一个 XY 问题 ...meta.stackexchange.com/questions/66377/what-is-the-xy-problem 您当前有 3 个嵌套循环(购买、销售和用户)。处理n users/buys/sells 需要 n^3 次操作。一旦 3 个输入中的任何一个超过一个微不足道的数字,这将变得非常缓慢。你说你想要“每日买入和卖出的比率”,但只保留有买入和卖出的日期会丢弃大量数据,否则比率为 0 或未定义,无论哪个日期都没有买入/卖出。您是否想要他们购买或出售日期的趋势?这是一个不同的问题。

标签: ruby-on-rails arrays ruby loops nested-loops


【解决方案1】:
daily_buy = user.buys.group_by(&:created_at)
 daily_sell = user.sells.group_by(&:created_at

  buys_and_sells = daily_buy + daily_sell

  totals = buys_and_sells.inject({}) do |hsh, transaction|
    hsh['buys'] ||= 0;
    hsh['sells']  ||= 0;
    hsh['buys'] += 1 if transaction.is_a?(Buy)
    hsh['sells'] += 1 if transaction.is_a?(Sell)
    hsh
  end

  hsh['buys']/hsh['sells']

我认为上面可能会这样做......而不是将每个东西收集到单独的数组中,将它们连接在一起,然后遍历组合数组中的每个项目,增加由返回的哈希的适当键中的计数注入。

【讨论】:

    【解决方案2】:

    在这种情况下,您不能在每次使用 for 循环时循环它们 这段代码会给你一个提示

    ar = [1,2,3,4,5]
    br = [1,2,3]
    
    array_l = (ar.length > br.length) ? ar.length : br.length
    
    for i in 0..array_l
        if ar[i] and br[i]
            puts ar[i].to_s + " " + br[i].to_s
        elsif ar[i]
          puts ar[i].to_s
        elsif br[i]
          puts br[i].to_s
        end
    end
    

    【讨论】:

    • 感谢您的提示,我已将我的问题扩展到包括我的实际问题。不确定这是否会有所帮助,但会考虑这一点。
    【解决方案3】:

    您可以通过以下方式连接两个数组并删除重复的元素:

    (a_array + b_array).uniq.each do |num|
      # code goes here
    end
    

    Uniq method API

    【讨论】:

    • 嘿,罗伊,谢谢你的提示。虽然我的问题已经包含了我的实际问题,但请看一下并告诉我您的想法。
    猜你喜欢
    • 2016-07-23
    • 1970-01-01
    • 2016-02-23
    • 2015-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-20
    • 2021-04-23
    相关资源
    最近更新 更多