7

ActiveRecord オブジェクトの 2 要素配列がありますslots_to_import。これらのオブジェクトにはbegin_at列があるため、属性があります。begin_at一意の値を持つオブジェクトを取得しようとしていました。残念ながら、slots_to_import.uniq_by(&:begin_at)うまくいきませんでした。ただし、begin_at2 つのオブジェクトの値は同じです。

(rdb:1) p slots_to_import.first.begin_at == slots_to_import.last.begin_at
true
(rdb:1) p slots_to_import.uniq_by(&:begin_at).map(&:begin_at)
[Mon, 26 Nov 2012 19:00:00 UTC +00:00, Mon, 26 Nov 2012 19:00:00 UTC +00:00]
(rdb:1) p [slots_to_import.first.begin_at, slots_to_import.last.begin_at].uniq
[Mon, 26 Nov 2012 19:00:00 UTC +00:00, Mon, 26 Nov 2012 19:00:00 UTC +00:00]

もう少しチェックしてください:

(rdb:1) p [slots_to_import.first.begin_at.to_datetime, slots_to_import.last.begin_at.to_datetime].uniq
[Mon, 26 Nov 2012 19:00:00 +0000]
(rdb:1) p [slots_to_import.first.begin_at.usec, slots_to_import.last.begin_at.usec].uniq
[0]
(rdb:1) p [slots_to_import.first.begin_at.to_f, slots_to_import.last.begin_at.to_f].uniq
[1353956400.0]
(rdb:1) p [slots_to_import.first.begin_at.utc, slots_to_import.last.begin_at.utc].uniq
[Mon, 26 Nov 2012 19:00:00 +0000]
(rdb:1) p [slots_to_import.first.begin_at, slots_to_import.last.begin_at].uniq
[Mon, 26 Nov 2012 19:00:00 UTC +00:00, Mon, 26 Nov 2012 19:00:00 UTC +00:00]

おそらく uniq はそれらが同じオブジェクトであるかどうかをチェックしていると思いました(そうではないため)。しかし、いいえ、私のRailsコンソールでのいくつかのnoodlingは、オブジェクトIDチェックを使用していないことを示しました:

1.8.7 :111 > x = Time.zone.parse("Mon, 29 Oct 2012 19:29:17 UTC +00:00")
 => Mon, 29 Oct 2012 19:29:17 UTC +00:00 
1.8.7 :112 > y = Time.zone.parse("Mon, 29 Oct 2012 19:29:17 UTC +00:00")
 => Mon, 29 Oct 2012 19:29:17 UTC +00:00 
1.8.7 :113 > x == y
 => true 
1.8.7 :114 > [x, y].uniq
 => [Mon, 29 Oct 2012 19:29:17 UTC +00:00] 

Ruby 1.8.7p358 と ActiveSupport 3.2.0 を使用しています。ところで、 を追加するだけで自分の問題を解決できますがto_datetime、変換なしではなぜこれが機能しないのか、本当に興味があります。

4

3 に答える 3

1

単純なTimeオブジェクトを扱っていると思ったのでtime.c、Ruby プラットフォーム ソース (1.9.3) から調べてみました。それらが Ruby 1.9.3Timeオブジェクトである場合は、次を試すことができます。

[x.to_r, y.to_r]

今、私はあなたがActiveSupport::TimeWithZoneオブジェクトを扱っていることを知っています。(提案として、次回質問を投稿する際に、このような重要な情報について言及することをお勧めします。) の本文は次のActiveSupport::TimeWithZone#eql?とおりです。

def eql?(other)
  utc == other
end

そして、ここにハッシュ関数があります:

alias :hash, :to_i

したがって、次のステップは、 から得られるものを示すことです[x.utc, y.utc, x.to_i, y.to_i, x.utc.class, y.utc.class]

于 2012-10-30T04:23:27.720 に答える
0

異なるマイクロ秒は私の推測です。2 つのオブジェクトは同じ検査文字列を表示できますが、同じではありません。

于 2012-10-30T01:05:51.323 に答える
0
irb(main):017:0> x = 'a'
=> "a"
irb(main):018:0> y = 'a'
=> "a"
irb(main):019:0> x == y
=> true
irb(main):020:0> [x,y].uniq
=> ["a"]
irb(main):021:0> x.object_id == y.object_id
=> false
irb(main):024:0> x.hash == y.hash
=> true

Ruby の等価性テストは、参照ではなく値に基づいています。それらが同じオブジェクトを参照しているかどうかを比較したい場合は、比較する必要がありますo.object_id

于 2012-10-30T03:45:40.540 に答える