2010-05-08 90 views
1

正如您在下面的当前代码中所看到的,我发现基于属性recordable_id的重复项。我需要做的是根据四个匹配属性找到重复项:user_id,recordable_type,hero_type,recordable_id。我该如何修改代码?使用Array.map去除具有相同属性的“重复对象”

heroes = User.heroes 

for hero in heroes 
    hero_statuses = hero.hero_statuses 

    seen = [] 

    hero_statuses.sort! {|a,b| a.created_at <=> b.created_at } # sort by created_at 
    hero_statuses.each do |hero_status| 
    if seen.map(&:recordable_id).include? hero_status.recordable_id # check if the id has been seen already 
     hero_status.revoke 
    else 
     seen << hero_status # if not, add it to the seen array 
    end 
    end 
end 
+0

我想摆脱最近created_at日期的副本,留下最初创建的记录。 – keruilin 2010-05-08 01:35:08

回答

0

使用直红宝石(不是SQL服务器) :

heroes = User.heroes 

for hero in heroes 
    hero_statuses = hero.hero_statuses 

    seen = {} 

    hero_statuses.sort_by!(&:created_at) 
    hero_statuses.each do |status| 
    key = [status.user_id, status.recordable_type, status.hero_type, status.recordable_id] 
    if seen.has_key?(key) 
     status.revoke 
    else 
     seen[key] = status # if not, add it to the seen array 
    end 
    end 

    remaining = seen.values 
end 

进行查找,始终使用Hash(或Set,但在这里,我认为这将是很好的保持已保持状态)

注:我用sort_by!,但这是新1.9.2,所以在使用sort_by(或require "backports"

1

试试这个:

HeroStatus.all(:group => "user_id, recordable_type, hero_type, recordable_id", 
       :having => "count(*) > 1").each do |status| 
    status.revoke 
end 

编辑2 撤销所有最新的重复项执行以下操作:

HeroStatus.all(:joins => "(
    SELECT user_id, recordable_type, hero_type, 
       recordable_id, MIN(created_at) AS created_at 
    FROM  hero_statuses 
    GROUP BY user_id, recordable_type, hero_type, recordable_id 
    HAVING COUNT(*) > 1 
    ) AS A ON A.user_id   = hero_statuses.user_id   AND 
      A.recordable_type = hero_statuses.recordable_type AND 
      A.hero_type  = hero_statuses.hero_type  AND 
      A.recordable_id = hero_statuses.recordable_id AND 
      A.created_at  < hero_statuses.created_ 
").each do |status| 
    status.revoke 
end 
+0

不错。这让我更加接近。这是我忘了提到的另一个皱纹。我想摆脱最近created_at日期的重复项,留下最初创建的记录。 – keruilin 2010-05-08 01:34:41

+0

更新了答案,看看。 – 2010-05-08 04:44:08

+0

thx kan!这很好。我正在寻找基于ruby的答案,所以要检查marc的。但感谢您的协助! – keruilin 2010-05-08 09:29:09

相关问题