ruby 如何将数组的元素移动到数组的开头

pdtvr36n  于 2023-01-16  发布在  Ruby
关注(0)|答案(3)|浏览(99)

我想把索引为2的元素移到数组[1, 2, 3, 4]的开头,得到的数组应该看起来像[3, 1, 2, 4]
我的解决方案是执行以下操作
[3] + ([1, 2, 3, 4] - [3])
有没有更好的办法?

2wnc66cl

2wnc66cl1#

一种方法,从数组中取出前n个元素并将它们旋转一个,然后将其余元素加回。

def rotate_first_n_right(arr, n)
  arr[0...n].rotate(-1) + arr[n..-1]
end

rotate_first_n_right([1,2,3,4], 3)
# => [3, 1, 2, 4]

如果我们尝试在太短的数组上使用它,这确实会失败,因为arr[n..-1]切片将生成nil,这将在我们尝试将其添加到第一个数组时导致错误。
我们可以通过将两个切片都展开到一个列表中来解决这个问题。

def rotate_first_n_right(arr, n)
  [*arr[0...n].rotate(-1), *arr[n..-1]]
end

要了解为什么这样做,一个非常简单的例子:

[*[1, 2, 3], *nil]
# => [1, 2, 3]

这个例子的一个问题是,如果3在数组中出现不止一次,会发生什么。

[1,2,3,3,3,4] - [3]
# => [1, 2, 4]
myss37ts

myss37ts2#

不知道你说的“旋转”是什么意思,因为这不完全是一个旋转,但你可以去

def move_element_to_front(arr, idx)
  # ruby >= 2.6 arr.dup.then {|a| a.unshift(a.delete_at(idx)) } 
  arr = arr.dup
  arr.unshift(arr.delete_at(idx))
end

这会将idx处的元素移动到返回的Array中的第一个位置

xiozqbni

xiozqbni3#

def move_element_to_front(arr, idx)
  [arr[idx]].concat(arr[0,idx], arr[idx+1..])
end
arr = [:dog, :cat, :pig, :hen]
move_element_to_front(arr, 2)
  #=> [:pig, :dog, :cat, :hen]
move_element_to_front(arr, 0)
  #=> [:dog, :cat, :pig, :hen]
move_element_to_front(arr, 3)
  #=> [:hen, :dog, :cat, :pig]

该方法的操作线可替换地表示为

[arr[idx], *arr[0,idx], *arr[idx+1..]]

相关问题