module ArrayElementMove
MustBeUniqArray = Class.new(StandardError)
ItemNotInArray = Class.new(StandardError)
def self.up!(array, item)
self.check_if_uniq!(array)
return array if array.first == item
position = array.index(item) || raise(ItemNotInArray)
array.insert((position - 1), array.delete_at(position))
end
def self.down!(array, item)
self.check_if_uniq!(array)
return array if array.last == item
position = array.index(item) || raise(ItemNotInArray)
array.insert((position + 1), array.delete_at(position))
end
def self.check_if_uniq!(array)
raise MustBeUniqArray if array.size != array.uniq.size
end
end
规格:
require 'spec_helper'
RSpec.describe ArrayElementMove do
let(:arr) { [1,2,3,4,5,6] }
it do
ArrayElementMove.up!(arr, 4)
expect(arr).to eq([1,2,4,3,5,6])
expect(ArrayElementMove.up!(arr, 4).to eq([1,4,2,3,5,6])
expect(arr).to eq([1,4,2,3,5,6])
ArrayElementMove.up!(arr, 4)
expect(arr).to eq([4,1,2,3,5,6])
ArrayElementMove.up!(arr, 4)
expect(arr).to eq([4,1,2,3,5,6])
end
it do
ArrayElementMove.down!(arr, 4)
expect(arr).to eq([1,2,3,5,4,6])
expect(ArrayElementMove.down!(arr, 4)).to eq([1,2,3,5,6,4])
expect(arr).to eq([1,2,3,5,6,4])
expect(ArrayElementMove.down!(arr, 4)).to eq([1,2,3,5,6,4])
expect(arr).to eq([1,2,3,5,6,4])
end
context 'when non uniq array' do
let(:arr) { [1,4,2,3,4,5,6] }
it do
expect { ArrayElementMove.down!(arr, 3) }.to raise_exception(ArrayElementMove::MustBeUniqArray)
expect(arr).to eq([1,4,2,3,4,5,6])
end
it do
expect { ArrayElementMove.down!(arr, 3) }.to raise_exception(ArrayElementMove::MustBeUniqArray)
expect(arr).to eq([1,4,2,3,4,5,6])
end
end
context 'when non existing item' do
it do
expect { ArrayElementMove.up!(arr, 9) }.to raise_exception(ArrayElementMove::ItemNotInArray)
expect(arr).to eq([1,2,3,4,5,6])
end
it do
expect { ArrayElementMove.up!(arr, 9) }.to raise_exception(ArrayElementMove::ItemNotInArray)
expect(arr).to eq([1,2,3,4,5,6])
end
end
end
8条答案
按热度按时间ufj5ltwl1#
没有比这更简单的了:
pbossiut2#
UPD:伙计们,它与dest〉src一起工作得很好:
你还能期望什么呢?0,2,1,3,4?我不会称之为dest=3
sg24os4d3#
初学者说明
这些答案很棒。我正在寻找更多关于这些答案如何工作的解释。下面是上面的答案中发生的事情,如何通过值切换元素,以及文档链接。
这是因为
arr.delete_at(index)
删除了指定索引处的元素(在上面的例子中为'7'),并返回该索引中的值。因此,运行arr.delete_at(7)
将产生:把它们放在一起,
insert
方法现在将把这个“h”元素放在位置2。为了清楚起见,将其分为两个步骤:按值切换元素
假设你想将数组中值为“h”的元素移动到位置2,而不管它的位置如何。这可以很容易地用index方法完成:
注意:上面的代码假设数组中只有一个“h”值。
文件
v1l68za44#
如果你想交换的话,最好的方法是:
0pizxfdo5#
如果你不关心数组中其他元素的位置,你可以使用.rotate!(注意这个方法末尾的!改变了实际的数组)方法。
这将获取索引为7的元素8,并将其旋转到索引为2。
9cbw7uwe6#
这里的答案并没有涵盖这两种可能的情况。虽然问题处理的是
origin
索引高于destination
,但如果相反,那么下面的解决方案将不起作用:这是因为删除2处的值会将数组中所有(2以上)的内容向下移动1。现在我们的目标索引7指向索引8处的内容。
为了解决这个问题,我们需要检查
origin
是否小于destination
,如果是,从destination
中减去1。说明
用更少的数字来思考这个问题可能会有所帮助。考虑:
我想把
:jane
移到:tama
的前面。我看到:jane
在位置1
,而:tama
当前在位置3
。我想我会很有效率,并根据我现在知道的正确位置以一行程序的形式完成这一操作:这是否达到了我的预期结果?不,
:jane
在:tama
之后。为什么会发生这种情况?因为数组成员的索引在被删除成员的点之上发生了变化,所以你假设的引用
delete_at
之前的成员的索引现在已经改变了。要正确地做到这一点,你最好先删除:jane
,然后再次查看employees
以确定:tama
的索引,现在是2
而不是3
,然后将:jane
插入2
。rnmwe5a27#
不是更好用途:
?
1szpjjfi8#
如果您正在寻找在数组中上下移动uniq项的解决方案:
规格: