Arrays 在ruby中基于引用数组对结构进行排序

Arrays 在ruby中基于引用数组对结构进行排序,arrays,ruby,Arrays,Ruby,我有一个结构定义为 Player = Struct.new(:name, :level) 和一个样本数组 levels = [ 'level-1','level-2','beta','alpha','level4','level7'] 我想对结构进行排序,使其成员按所述级别的递增顺序出现 乙二醇 你几乎成功了。sort_by block的结果应该是您想要比较的结果。您希望使用级别索引,而不是包含级别索引的数组 arr.sort_by { |e| levels.index(e.level) }

我有一个结构定义为

Player = Struct.new(:name, :level)
和一个样本数组

levels = [ 'level-1','level-2','beta','alpha','level4','level7']
我想对结构进行排序,使其成员按所述级别的递增顺序出现 乙二醇


你几乎成功了。sort_by block的结果应该是您想要比较的结果。您希望使用级别索引,而不是包含级别索引的数组

arr.sort_by { |e| levels.index(e.level) }

确保你的水平线是正确的。您可能希望使用常量来避免输入错误。

您已经差不多做到了。sort_by block的结果应该是您想要比较的结果。您希望使用级别索引,而不是包含级别索引的数组

arr.sort_by { |e| levels.index(e.level) }

确保你的水平线是正确的。您可能希望使用常量来避免输入错误。

这里有一个解决方案,它的计算复杂度接近于开,因为哈希查找的时间不是非常恒定的

我们得到:

Player = Struct.new(:name, :level)

arr = [["Tom", "level4"], ["Ryan", "beta"], ["Chris", "alpha"],
       ["Drew", "level4"]].map { |a| Player.new(*a) }
  #=> [#<struct Player name="Tom",   level="level4">,
  #    #<struct Player name="Ryan",  level="beta">,
  #    #<struct Player name="Chris", level="alpha">,
  #    #<struct Player name="Drew",  level="level4">]
然后

步骤如下:

h = arr.group_by(&:level)
  #=> {"level4"=>[#<struct Player name="Tom",   level="level4">,
  #               #<struct Player name="Drew",  level="level4">],
  #    "beta"  =>[#<struct Player name="Ryan",  level="beta">],
  #    "alpha" =>[#<struct Player name="Chris", level="alpha">]}

这是一个计算复杂度接近于On的解决方案,因为哈希查找不是固定时间

我们得到:

Player = Struct.new(:name, :level)

arr = [["Tom", "level4"], ["Ryan", "beta"], ["Chris", "alpha"],
       ["Drew", "level4"]].map { |a| Player.new(*a) }
  #=> [#<struct Player name="Tom",   level="level4">,
  #    #<struct Player name="Ryan",  level="beta">,
  #    #<struct Player name="Chris", level="alpha">,
  #    #<struct Player name="Drew",  level="level4">]
然后

步骤如下:

h = arr.group_by(&:level)
  #=> {"level4"=>[#<struct Player name="Tom",   level="level4">,
  #               #<struct Player name="Drew",  level="level4">],
  #    "beta"  =>[#<struct Player name="Ryan",  level="beta">],
  #    "alpha" =>[#<struct Player name="Chris", level="alpha">]}

我只想指出,您可以通过对levels数组进行预索引来优化时间复杂度,例如,将其转换为{=>}散列,这样您就不必调用。index repeatedly为@maxpleaner的建议添加一些内容:对于arr=[[Tom,level4],[Ryan,beta],[Chris,alpha]]。map{a | Player.new*a}=>[,],构建level_to_idx=levels.each_与_index.to_a.to_h=>{level-1=>0,level-2=>1,beta=>2,alpha=>3,level-4=>4,level-7=>5},…@CarySwoveland我以前在采访中提出过这个问题,我总是说它将从^2开始,但我突然想问这是真的吗?sort_by的时间复杂度为ON?…然后arr.sort_by{i | level_to_idx[i.level]}=>[,]。这将计算复杂度从**2降低到了Onlogn。@maxpleaner,你在说什么?我说的是Onlogn。坦白:我在一篇被删除的评论中说到。我只想指出,通过对levels数组进行预索引,可以优化这里的时间复杂度,例如,将其转换为{=>}散列,这样您就不必调用。重复索引可以让@maxpleaner的建议更生动:对于arr=[[Tom,level4],[Ryan,beta],[Chris,alpha]]。map{| a | Player.new*a}=>[,],构造级别u to_idx=levels.each_与_index.to_a.to_h=>{level-1=>0,level-2=>1,beta=>2,alpha=>3,level4=>4,level7=>5},…@CarySwoveland我以前在采访中提出过这个问题,我总是说这是从^2到^2,但我突然想问,这是否真的是真的?排序的时间复杂度是吗?…然后arr.sort_by{I | level|u to_idx[I.level]=>[,]。这将计算复杂度从**2降低到Onlogn。@maxpleaner,你在说什么?我说的是Onlogn。坦白:我在删除的评论中说了On。
    arr.group_by(&:level).values_at(*levels).flatten.compact
  #=>[#<struct Player name="Ryan",  level="beta">,
  #   #<struct Player name="Chris", level="alpha">,
  #   #<struct Player name="Tom",   level="level4">,
  #   #<struct Player name="Drew",  level="level4">]
h = arr.group_by(&:level)
  #=> {"level4"=>[#<struct Player name="Tom",   level="level4">,
  #               #<struct Player name="Drew",  level="level4">],
  #    "beta"  =>[#<struct Player name="Ryan",  level="beta">],
  #    "alpha" =>[#<struct Player name="Chris", level="alpha">]}
a = h.values_at(*levels)
  #=> [nil,
  #    nil,
  #    [#<struct Player name="Ryan",  level="beta">],
  #    [#<struct Player name="Chris", level="alpha">],
  #    [#<struct Player name="Tom",   level="level4">,
  #     #<struct Player name="Drew",  level="level4">],
  #    nil]
b = a.compact
  #=>  [[#<struct Player name="Ryan",  level="beta">],
  #     [#<struct Player name="Chris", level="alpha">],
  #     [#<struct Player name="Tom",   level="level4">,
  #      #<struct Player name="Drew",  level="level4">]]
c = b.flatten
  #=>  [#<struct Player name="Ryan",  level="beta">,
  #     #<struct Player name="Chris", level="alpha">,
  #     #<struct Player name="Tom",   level="level4">,
  #     #<struct Player name="Drew",  level="level4">]