使用重复模式删除重复记录和记录的算法

时间:2018-04-09 12:50:10

标签: ruby algorithm

我在数据库中有一些记录跟踪某些项目的价格开发。这些记录通常包含重复和重复的价格变化序列。我需要清理它们。请考虑以下事项:

Record = Struct.new(:id, :created_at, :price)
records = [
  Record.new(1, Date.parse('2017-01-01'), 150_000),
  Record.new(2, Date.parse('2017-01-02'), 150_000),
  Record.new(3, Date.parse('2017-01-03'), 130_000),
  Record.new(4, Date.parse('2017-01-04'), 140_000),
  Record.new(5, Date.parse('2017-01-05'), 140_000),
  Record.new(6, Date.parse('2017-01-06'), 137_000),
  Record.new(7, Date.parse('2017-01-07'), 140_000),
  Record.new(8, Date.parse('2017-01-08'), 140_000),
  Record.new(9, Date.parse('2017-01-09'), 137_000),
  Record.new(10, Date.parse('2017-01-10'), 140_000),
  Record.new(11, Date.parse('2017-01-11'), 137_000),
  Record.new(12, Date.parse('2017-01-12'), 140_000),
  Record.new(13, Date.parse('2017-01-13'), 132_000),
  Record.new(14, Date.parse('2017-01-14'), 130_000),
  Record.new(14, Date.parse('2017-01-15'), 132_000)
]

政策应该用简单的话说:

  1. 立即删除任何完全相同价格的重复项。
  2. 删除记录序列的所有记录,其中两个价格相同的两个或两个或更多跳跃(例如[120,110,120,110]但不是[120,110,120]),所以只有最初的价格变化得以保留。
  3. 在上面的例子中,我期望的输出应该是:

    [
      Record#<id: 1, created_at: Date#<'2017-01-01'>, price: 150_000>,
      Record#<id: 3, created_at: Date#<'2017-01-03'>, price: 130_000>,
      Record#<id: 4, created_at: Date#<'2017-01-04'>, price: 140_000>,
      Record#<id: 6, created_at: Date#<'2017-01-06'>, price: 137_000>,
      Record#<id: 13, created_at: Date#<'2017-01-13'>, price: 132_000>,
      Record#<id: 14, created_at: Date#<'2017-01-14'>, price: 130_000>,
      Record#<id: 14, created_at: Date#<'2017-01-14'>, price: 132_000>
    ]
    

    注意:这是我暂时想到的最复杂的例子,如果我找到更多,我会更新问题。

1 个答案:

答案 0 :(得分:0)

亲爱的先生,您可以毫无疑问地帮助您应对挑战,在这里:

records_to_delete = []

# Cleanup duplicates
records.each_with_index do |record, i|
  if i != 0 && record.price == records[i - 1].price
    records_to_delete << record.id
  end
end

records = records.delete_if{|record| records_to_delete.include?(record.id)}

# Remove repetitions
records_to_delete = []

records.each_with_index do |record, i|
  if record.price == records[i + 2]&.price && records[i + 1]&.price == records[i + 3]&.price
    records_to_delete << records[i+2].id
    records_to_delete << records[i+3].id
  end
end

records = records.delete_if{|record| records_to_delete.uniq.include?(record.id)}