我想将索引 2 处的元素移动到数组的开头
[1, 2, 3, 4]
,生成的数组应该类似于 [3, 1, 2, 4]
。
我的解决方案是执行以下操作
[3] + ([1, 2, 3, 4] - [3])
有更好的方法吗?
一种方法,从数组中获取前
n
元素并将它们旋转 1,然后添加回剩余元素。
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]
不确定“旋转”是什么意思,因为这不完全是旋转,但你可以选择
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
中的第一个位置
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..]]