简体   繁体   English

使用Ruby使哈希值相互查找

[英]Making hashes find each other by their values using Ruby

I have a couple time_tables in this array. 我在此数组中有几个time_tables There are four time_tables that are related to each other in a linear way by their start_location - end_location and start_date - end_date . 有四个time_tables通过它们的start_location - end_locationstart_date - end_date相互线性关联。

When the first time_table ends, the other time_table starts, and so on. 当第一个time_table结束时,另一个time_table开始,依此类推。

My code: 我的代码:

arr =   [
      { name: 01, start_date: '2014-04-24 22:03:00', start_location: 'A', end_date: '2014-04-24 22:10:00', end_location: 'B' },
      { name: 05, start_date: '2014-04-24 22:10:00', start_location: 'C', end_date: '2014-04-24 23:10:00', end_location: 'D' },
      { name: 01, start_date: '2014-04-24 17:10:00', start_location: 'X', end_date: '2014-04-24 20:10:00', end_location: 'B' },
      { name: 01, start_date: '2014-04-24 17:10:00', start_location: 'Z', end_date: '2014-04-24 20:10:00', end_location: 'B' },
      { name: 06, start_date: '2014-04-24 20:15:00', start_location: 'B', end_date: '2014-04-24 22:10:00', end_location: 'C' },
      { name: 03, start_date: '2014-04-24 23:15:00', start_location: 'D', end_date: '2014-04-24 00:10:00', end_location: 'E' }
    ]
new_array = []

i = 0
while i <= 5 do
  if arr[i][:end_location] == arr[i+1][:start_location] && arr[i][:start_date] <= arr[i+1][:start_date]
    new_array << arr[i+1]
  end
  i = i + 1
end

This is the result that I want: 这是我想要的结果:

  # My expexpected result will be this:
  #     [
  #     { name: 01, start_date: '2014-04-24 22:03:00', start_location: 'A', end_date: '2014-04-24 22:10:00', end_location: 'B' },
  #    { name: 06, start_date: '2014-04-24 22:15:00', start_location: 'B', end_date: '2014-04-24 22:20:00', end_location: 'C' },
  #    { name: 05, start_date: '2014-04-24 22:20:00', start_location: 'C', end_date: '2014-04-24 23:10:00', end_location: 'D' },
  #    { name: 03, start_date: '2014-04-24 23:15:00', start_location: 'D', end_date: '2014-04-24 00:10:00', end_location: 'E' }
  # 

  ]

but my algorithm is seems to be bad. 但是我的算法似乎不好。 Thank you for insights to make this work. 感谢您为这项工作提供的见识。

This will "join" your time series by consecutive end and start location. 这将通过连续的结束和开始位置“加入”您的时间序列。

 def span x; x[:end_location].ord - x[:start_location].ord; end
 def diff x, y; x[:start_location].ord - y[:start_location].ord; end
 arr = arr.sort_by { |x| [x[:start_location], span(x)] }
 prev = arr[0]
 arr = arr.slice_before { |e|
   prev, prev2 = e, prev
   diff(prev, prev2) != 0
 }.to_a.map(&:first).chunk(&method(:span)).first[1]

For example, I get 例如,我得到

 arr.map { |x| [x[:start_location], x[:end_location] }
 => [["A", "B"], ["B", "C"], ["C", "D"], ["D", "E"]]

Aren't you really looking for the longest linear sub sequent time tables ? 您不是真的在寻找最长的线性后续时间表吗? I wanted to clarify that through comments but I didn't have the permission to comment. 我想通过评论来澄清这一点,但我无权发表评论。 Also there is a difference between the value of start_date of B (and start_location B) in input and the output, so I'm assuming it's a mistake. 在输入和输出中B的start_date(和start_location B)的值之间也存在差异,所以我假设这是一个错误。

I have written the solution considering you want to find the longest linear sub sequent time tables. 考虑到您想要找到最长的线性后续时间表,我已经编写了解决方案。

require 'date'

def getLLTT(time_tables)

    longest = []
    time_tables.sort_by! do |time_table|
        DateTime.parse(time_table[:start_date]).to_time
    end

    0.upto(time_tables.size-1) do |i|

        long_for_i = [time_tables[i]]
        0.upto(i-1) do |j|
            j_end_date = DateTime.parse(longest[j][-1][:end_date]).to_time
            i_start_date = DateTime.parse(time_tables[i][:start_date]).to_time
            if j_end_date <= i_start_date 
                if longest[j][-1][:end_location].eql? time_tables[i][:start_location]
                    if longest[j].size + 1 > long_for_i.size
                        long_for_i = longest[j] + [time_tables[i]]
                    end
                end
            end
        end

        longest[i] = long_for_i
    end
    return longest[-1]
end

puts getLLTT(arr)

So given the input : 所以给定输入:

arr =   [
{ name: 01, start_date: '2014-04-24 22:03:00', start_location: 'A', end_date: '2014-04-24 22:10:00', end_location: 'B' },
  { name: 05, start_date: '2014-04-24 22:10:00', start_location: 'C', end_date: '2014-04-24 23:10:00', end_location: 'D' },
  { name: 01, start_date: '2014-04-24 17:10:00', start_location: 'X', end_date: '2014-04-24 20:10:00', end_location: 'B' },
  { name: 01, start_date: '2014-04-24 17:10:00', start_location: 'Z', end_date: '2014-04-24 20:10:00', end_location: 'B' },
  { name: 06, start_date: '2014-04-24 20:15:00', start_location: 'B', end_date: '2014-04-24 22:10:00', end_location: 'C' },
  { name: 03, start_date: '2014-04-24 23:15:00', start_location: 'D', end_date: '2014-04-24 00:10:00', end_location: 'E' }
]

The output will be : 输出将是:

[
{:name=>1, :start_date=>"2014-04-24 17:10:00", :start_location=>"Z", :end_date=>"2014-04-24 20:10:00", :end_location=>"B"}
{:name=>6, :start_date=>"2014-04-24 20:15:00", :start_location=>"B", :end_date=>"2014-04-24 22:10:00", :end_location=>"C"}
{:name=>5, :start_date=>"2014-04-24 22:10:00", :start_location=>"C", :end_date=>"2014-04-24 23:10:00", :end_location=>"D"}
{:name=>3, :start_date=>"2014-04-24 23:15:00", :start_location=>"D", :end_date=>"2014-04-24 00:10:00", :end_location=>"E"}
]

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

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