我想把索引为2的元素移到数组[1, 2, 3, 4]的开头,得到的数组应该看起来像[3, 1, 2, 4]。我的解决方案是执行以下操作[3] + ([1, 2, 3, 4] - [3])有没有更好的办法?
[1, 2, 3, 4]
[3, 1, 2, 4]
[3] + ([1, 2, 3, 4] - [3])
2wnc66cl1#
一种方法,从数组中取出前n个元素并将它们旋转一个,然后将其余元素加回。
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,这将在我们尝试将其添加到第一个数组时导致错误。我们可以通过将两个切片都展开到一个列表中来解决这个问题。
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在数组中出现不止一次,会发生什么。
3
[1,2,3,3,3,4] - [3] # => [1, 2, 4]
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中的第一个位置
idx
Array
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..]]
3条答案
按热度按时间2wnc66cl1#
一种方法,从数组中取出前
n
个元素并将它们旋转一个,然后将其余元素加回。如果我们尝试在太短的数组上使用它,这确实会失败,因为
arr[n..-1]
切片将生成nil
,这将在我们尝试将其添加到第一个数组时导致错误。我们可以通过将两个切片都展开到一个列表中来解决这个问题。
要了解为什么这样做,一个非常简单的例子:
这个例子的一个问题是,如果
3
在数组中出现不止一次,会发生什么。myss37ts2#
不知道你说的“旋转”是什么意思,因为这不完全是一个旋转,但你可以去
这会将
idx
处的元素移动到返回的Array
中的第一个位置xiozqbni3#
该方法的操作线可替换地表示为