【问题标题】:Insert into array at specific position based on array content Ruby根据数组内容 Ruby 在特定位置插入数组
【发布时间】:2017-04-04 00:08:17
【问题描述】:

我有一个按该对象的一个​​属性排序的对象数组,我想在其中插入另一个对象,该位置由该对象的该属性确定。

基本上,类似:
foo = [User(score: 10), User(score: 8), User(score: 5), User(score: 1)]
在那个数组中,我想插入:
bar = User(score: 6)
在正确的索引处,因此在本例中为索引 2。

我可以将它推送到数组然后sort_by,但我想知道是否有更好的解决方案来解决这个问题(某种插入方法,您可以传递一个块来定义索引)。

提前致谢:)

【问题讨论】:

标签: ruby-on-rails arrays ruby


【解决方案1】:

代码

def insert_new(arr, new_instance)
  arr.insert(arr.index { |instance| new_instance.score >= instance.score } || -1,
    new_instance)
end

示例

class A
  def initialize(user, score)
    @user, @score = user, score
  end
end

arr = [A.new("Hank", 10), A.new("Lois", 8), A.new("Billy-Bob", 6),
       A.new("Trixy", 4)]
  #=> [#<A:0x007fad7b02fd70 @user="Hank", @score=10>,
  #    #<A:0x007fad7b02fcf8 @user="Lois", @score=8>,
  #    #<A:0x007fad7b02fc80 @user="Billy-Bob", @score=6>,
  #    #<A:0x007fad7b02fbe0 @user="Trixy", @score=4>]

insert_new(arr, A.new("Hubert", 7))
  #=> [#<A:0x007fad7a027450 @user="Hank", @score=10>,
  #    #<A:0x007fad7a0273b0 @user="Lois", @score=8>,
  #    #<A:0x007fad7a850b90 @user="Hubert", @score=7>,
  #    #<A:0x007fad7a027310 @user="Billy-Bob", @score=6>,
  #    #<A:0x007fad7a027270 @user="Trixy", @score=4>] 
insert_new(arr, A.new("Zelda", 2))
  #=> [#<A:0x007fad7a027450 @user="Hank", @score=10>,
  #    #<A:0x007fad7a0273b0 @user="Lois", @score=8>,
  #    #<A:0x007fad7a850b90 @user="Hubert", @score=7>, 
  #    #<A:0x007fad7a027310 @user="Billy-Bob", @score=6>,
  #    #<A:0x007fad7a027270 @user="Trixy", @score=4>,
  #    #<A:0x007fad7b876128 @user="Zelda", @score=2>]
insert_new(arr, A.new("Slim", 8))
  #    Slim is inserted between Hank and Lois
insert_new(arr, A.new("Rhonda", 8))
  #    Rhonda is inserted between Hank and Slim

注意

注意塞尔达被插入到最后。在这种情况下,

arr.index { |instance| new_instance.score >= instance.score } #=> nil

因此使用了索引-1 (... || -1),这意味着该值将插入到arr 的最后一个元素之后。见String#insert

【讨论】:

  • 嘿,Cary,我不知道你为什么被否决,但这是最好的答案。默认-1真的很聪明,哈哈。也感谢您提供全面的示例。感谢您的努力!你真的帮了我:)
【解决方案2】:

如果你想避免完全排序,你可以找到索引然后插入。类似的东西 -

insert_index = foo.index { |x| x.score <= new_user.score } || -1
foo.insert(insert_index, new_user)

【讨论】:

  • 这确实是一个聪明的解决方案!这里唯一的问题是,如果 new_user.score 总是小于其他分数,它就不会像应有的那样插入到末尾。 Cary Swoveland 给了你一个类似的答案,如果 foo.index 返回 nil,他添加了一个默认值 -1。但这绝对是正确的方法,我认为!谢谢拉胡尔:)
猜你喜欢
  • 1970-01-01
  • 2012-06-14
  • 2020-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-30
  • 2016-08-16
相关资源
最近更新 更多