Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby是否有数据库或数据结构来实现关系矩阵?_Ruby_Database_Data Structures_Matrix - Fatal编程技术网

Ruby是否有数据库或数据结构来实现关系矩阵?

Ruby是否有数据库或数据结构来实现关系矩阵?,ruby,database,data-structures,matrix,Ruby,Database,Data Structures,Matrix,我有一个非常简单的数据集 产品 属性 交叉表:产品的相关属性 red blue modern old fashion (50+ Entries) Jeans myway 0% 100% 30% 30% Polo Shirt 100% 0% 10% 40% (500+ Entries) 在应用程序中,选择红色、蓝色等属性。。并根据相关性对产品进行排序

我有一个非常简单的数据集

  • 产品
  • 属性
  • 交叉表:产品的相关属性

                      red    blue   modern   old fashion  (50+ Entries)
         Jeans myway    0%   100%    30%       30%
         Polo Shirt   100%     0%    10%       40%
         (500+ Entries)
    
在应用程序中,选择红色、蓝色等属性。。并根据相关性对产品进行排序

存储数据的最佳方式是什么?ruby有好的数据结构(库)吗

(不要告诉我如何用传统的3表sql和active record实现它。我已经知道了。我正在寻找更好的解决方案。)

一种方法是使用散列:

"red" => {"Jeans myway" => 0, "Polo Shirt" => 100}, "blue" => {..
这是一种好方法吗?我应该如何将其存储到文件中

[编辑] 更好的解决方案:如果我使用关系数据库,我必须将矩阵拆分为3个表产品、属性、属性和产品。我想将其存储在一个表/矩阵中,并像矩阵一样搜索/使用它


例如,我想选择属性“旧时尚”、“现代时尚”相关(>0)的产品,按相关性排序将返回“牛仔裤myway 0.09”、“马球衫0.04”。(相关性通过乘法计算。)

这里有一个适合您需要的解决方案。它允许您选择任意数量的产品或属性,并查看另一个轴中按权重乘积排序的值。它允许您将数据存储在CSV中,这样您就可以保留一个大的Excel文件,用于将来的调整

merge\u by
sort\u by
filter\u by
方法可用于指定获取结果时要应用的块

TESTDATA = <<ENDCSV
,red,blue,modern,old fashion,sexy
Jeans myway,0%,100%,30%,30%,70%
Polo Shirt,100%,0%,10%,40%,1%
Bra,100%,0%,100%,0%,100%
ENDCSV

def test
  products = RelationTable.load_from_csv( TESTDATA )

  p products.find( :col, 'old fashion','modern' )
  #=> [["Jeans myway", 9.0], ["Polo Shirt", 4.0]]

  p products.find( :row, 'Polo Shirt' )
  #=> [["red", 100.0], ["old fashion", 40.0], ["modern", 10.0]]

  p products.find( :col, 'sexy' )
  #=> [["Bra", 100.0], ["Jeans myway", 70.0], ["Polo Shirt", 1.0]]

  p products.find( :row, 'Polo Shirt','Bra' )
  #=> [["red", 100.0], ["modern", 10.0]]

  p products.find( :col, 'sexy','modern' )
  #=> [["Bra", 100.0], ["Jeans myway", 21.0], ["Polo Shirt", 0.1]]

  p products.find( :col, 'red', 'blue' )
  #=> []

  p products.find( :col, 'bogus' )
  #=> []
end

class RelationTable
  def self.load_from_csv( csv )
    require 'csv'
    data = CSV.parse(csv)
    self.new( data.shift[1..-1], data.map{ |r| r.shift }, data )
  end
  def initialize( col_names=[], row_names=[], weights=[] )
    @by_col = Hash.new{|h,k|h[k]=Hash.new(0)}
    @by_row = Hash.new{|h,k|h[k]=Hash.new(0)}
    row_names.each_with_index do |row,r|
      col_names.each_with_index do |col,c|
        @by_col[col][row] = @by_row[row][col] = weights[r][c].to_f
      end
    end
    # Multiply all weights, sort by weight (descending), only include non-zero
    merge_by{ |values| values.inject(1.0){ |weight,v| weight*v/100 }*100 }
    sort_by{ |key,value| [-value,key] }
    filter_by{ |key,value| value > 0 }
  end
  def merge_by(&proc);  @merge  = proc; end
  def sort_by(&proc);   @sort   = proc; end
  def filter_by(&proc); @filter = proc; end
  def find( row_or_col, *names )
    axis = (row_or_col == :row) ? @by_row : @by_col
    merge(axis.values_at(*names)).select(&@filter).sort_by(&@sort)
  end
  private
    # Turn an array of hashes into a hash of arrays of values,
    # and then merge the values using the merge_by proc
    def merge( hashes )
      if hashes.length==1
        hashes.first # Speed optimization; ignores the merge_by block
      else
        result = Hash.new{|h,k|h[k]=[]}
        hashes.each{ |h| h.each{ |k,v| result[k] << v } }
        result.each{ |k,values| result[k] = @merge[values] }
        result
       end
    end
end

test if __FILE__==$0
TESTDATA=[[“红色”,100.0],“老式”,40.0],“现代”,10.0]]
p products.find(:col,‘sexy’)
#=>[[“胸罩”,100.0],“牛仔裤myway”,70.0],“马球衫”,1.0]]
p产品。查找(:行,“马球衫”,“胸罩”)
#=>[[“红色”,100.0],“现代”,10.0]]
p products.find(:col,‘sexy’、‘modern’)
#=>[[“胸罩”,100.0],“牛仔裤myway”,21.0],“马球衫”,0.1]]
p products.find(:col,‘红色’、‘蓝色’)
#=> []
p products.find(:col,'bogus')
#=> []
结束
类关系表
定义自加载从csv(csv)加载
需要“csv”
data=CSV.parse(CSV)
self.new(data.shift[1..-1],data.map{r|r.shift},data)
结束
def初始化(列名称=[]、行名称=[]、权重=[])
@by|col=Hash.new{h,k|h[k]=Hash.new(0)}
@by|row=Hash.new{h,k|h[k]=Hash.new(0)}
行名称。每个带有索引do的行,r|
列名称。每个列都有索引do |列,c|
@按列[col][row]=@按列[row][col]=权重[r][c]。至
结束
结束
#乘以所有权重,按权重排序(降序),仅包括非零
通过{值}值合并{u。注入(1.0){权重,v{权重*v/100}*100}
按{键,值{value,键]}排序
按{|键,值|值>0}过滤|u
结束
def merge_by(&proc)@merge=proc;结束
def排序依据(&proc)@排序=进程;结束
def过滤器_by(&proc)@过滤器=程序;结束
def find(行或列,*名称)
轴=(行或列==:行)@按行:@按列
合并(axis.values_at(*names))。选择(&@filter)。按(&@sort)排序
结束
私有的
#将哈希数组转换为值数组的哈希,
#然后使用merge_by proc合并这些值
def合并(散列)
如果hashes.length==1
hashes.first#速度优化;忽略“按块合并”
其他的
result=Hash.new{| h,k | h[k]=[]}

hash.each{h}h.each{k,v | result[k]你说你在寻找一个比SQL+AR更好的解决方案。你能解释一下“更好”的标准是什么吗是吗?MySQL/PostgreSQL RDBMS是问题所在,使用基于文件的SQLite数据库还是内存数据库更好?您需要随着时间的推移更新关系,还是加载一次并读取关系?您是否只需要执行您描述的查询(选择一个属性并查看按相关性排序的产品)?我正在寻找更像矩阵的解决方案。请参阅我的编辑。