Ruby将对象插入现有的已排序对象数组

时间:2017-09-08 23:17:58

标签: ruby

我有以下现有Dog个对象数组,这些对象按age属性排序:

class Dog
  attr_accessor :age

  def initialize(age)
    @age = age
  end
end

dogs = [Dog.new(1), Dog.new(4), Dog.new(10)]

我想现在insert一个新的狗记录,让它进入阵列中的适当位置。

我想说我想插入这个对象:

another_dog = Dog.new(8)

我想将它插入数组中,并让它成为数组中的第三项。

这是一个人为的例子,旨在演示我如何特意将项目插入现有的有序数组中。我意识到我可以创建一个全新的数组并重新排序所有对象,但这不是我想要在这里做的。

谢谢!

2 个答案:

答案 0 :(得分:6)

这样做的一种惯用方法是只需追加然后排序。数组在Ruby中是可变的:

dogs.push(Dog.new(7)).sort_by!(&:age)

根据您的使用情况,您可能需要考虑提供更好性能的替代数据结构,例如二叉树。您可能还希望实施Comparable,在这种情况下,您可以简化为Array#sort!

答案 1 :(得分:6)

在Ruby 2.3+中,您可以使用Array#bsearch_index来确定需要传递给Array#insert的索引:

dogs = [Dog.new(1), Dog.new(4), Dog.new(10)]

another_dog = Dog.new(8)
insert_at = dogs.bsearch_index { |dog| dog.age >= another_dog.age }
dogs.insert(insert_at, another_dog)
puts dogs.inspect
# => [Dog.new(1), Dog.new(4), Dog.new(8), Dog.new(10)]

这只有在数组已经排序时才会有效(标准,当使用二进制搜索任何东西时),但听起来就是这样。

如果你正在使用Ruby< 2.3,你没有bsearch_index,但insert仍然可用,你可以自己快速搜索索引,然后使用insert