代码之家  ›  专栏  ›  技术社区  ›  collimarco

无序情侣在Ruby

  •  1
  • collimarco  · 技术社区  · 17 年前

    我想计算用户之间的相似性,这是相互的。

    similarity[:user1][:user2] == similarity[:user2][:user1]

    因此,最好使用:

    unordered_set(:user1, :user2) = 1
    unordered_set(:user2, :user1) += 1
    
    read_unordered_set(:user1, :user2) #=> 2
    read_unordered_set(:user2, :user1) #=> 2
    

    2 回复  |  直到 17 年前
        1
  •  6
  •   Philip Brocoum    17 年前
        2
  •  1
  •   bltxd    17 年前

    这里缺少的部分是<=>符号上的操作员。如果你定义一个,那么一个解决方案是:

    # We define our own <=> operation on symbols
    Symbol.class_eval do
      def <=>(other)
        self.to_s <=> other.to_s
      end
    end
    
    
    # Our set
    class UnorderedSet
      def initialize
        @hash = Hash.new
      end
    
      def [](k1, k2)
        @hash[[k1, k2].sort]
      end
    
      def []=(k1, k2, value)
        @hash[[k1, k2].sort] = value
      end
    
      def keys
        @hash.keys
      end
    
      def values
        @hash.values
      end
    
      def each
        @hash.each do |k, v|
          yield(k, v)
        end
      end
      include Enumerable
    end
    

    当然,我们为该容器提供了一些测试:

    if __FILE__ == $0
      require 'test/unit'
    
      class UnorderedSetTest < Test::Unit::TestCase
        def setup
          @set = UnorderedSet.new
        end
    
        def test_bracket_operators
          assert_equal(nil, @set[:unknown, :key])
    
          @set[:user1, :user2] = 1
          @set[:user2, :user1] += 1
    
          assert_equal(2, @set[:user1, :user2])
          assert_equal(2, @set[:user2, :user1])
        end
    
        def test_enumerability
          h = {
            [:user1, :user2] => "ruby",
            [:c, :d] => "is",
            [:b, :a] => "easy",
            [:f, :e] => "!"
          }
    
          h.each do |k, v|
            @set[*k] = v
          end
    
          assert_equal(h.values.sort, @set.values.sort)
          assert_equal(h.keys.collect { |k| k.sort }.sort, @set.keys.sort)
          assert_equal(h.to_a.collect { |k, v| [k.sort, v] }.sort, @set.to_a.sort)
        end
      end
    end
    

    推荐文章