我有一个排序的元素数组:
array = ["A", "B", "C", "D", "E"]
我定义了一系列元素,其中“键”是开始元素,“值”是结束元素:
range_1 = {"C" => "D"}
range_2 = {"B" => "E"}
如何编写代码以根据解析数组上方的范围返回子数组?
result_1 = ["C", "D"]
result_2 = ["B", "C", "D", "E"]
result_1 = array[array.index(range_1.keys.first)..array.index(range_1.values.first)]
result_2 = array[array.index(range_2.keys.first)..array.index(range_2.values.first)]
假设您的数组元素是唯一的:
array = ["A", "B", "C", "D", "E"]
range_1 = {"C" => "D"}
range_2 = {"B" => "E"}
def subarray(array, range)
from, to = range.first
idx_from = array.index(from)
idx_to = array.index(to)
array[idx_from..idx_to]
end
subarray(array, range_1) # => ["C", "D"]
subarray(array, range_2) # => ["B", "C", "D", "E"]
你这样做的方式有一种气味:
而不是使用类似的东西:
range_1 = {"C" => "D"}
range_2 = {"B" => "E"}
我会选择使用真实范围:
range_1 = 'C' .. 'D'
range_2 = 'B' .. 'E'
然后我可以省去使用,array
因为将范围转换为连续值数组非常容易。
range_1.to_a # => ["C", "D"]
range_2.to_a # => ["B", "C", "D", "E"]
[*range_1] # => ["C", "D"]
[*range_2] # => ["B", "C", "D", "E"]
如果中的值array
不是真正连续的,如示例中所示,那么我将使用索引值:
array = ["A", "B", "C", "D", "E"]
range_1 = 2 .. 3
range_2 = 1 .. 4
这使得检索值变得容易:
array = ["A", "B", "C", "D", "E"]
range_1 = 2 .. 3
range_2 = 1 .. 4
array[range_1] # => ["C", "D"]
array[range_2] # => ["B", "C", "D", "E"]
如果您需要使用实际值array
作为索引的符号名称,这将变得更加困难,类似于您现在正在做的事情,但如果您使用的是 Web 前端,那还不错。用户的大脑和眼睛是一笔不错的资产。
因为用例没有很好地定义,我们不能真正推荐更好的解决方案。我怀疑在这种情况下,您已经确定某种算法是最好的,现在您正试图使其发挥作用,但是当您感觉到房间的角落正在逼近时,熵就开始了。这是基于 a 的分析多年查看代码,而不是快速判断。
但是像这样的东西不是 ["A","B","C","D"]["B".."D"]。我进入“[]”:无法将字符串转换为整数
需要考虑的其他一点是哈希就像数组一样,只是它们允许更轻松地使用随机访问values_at
。
考虑一下:
array = %w[a b c d x y z]
hash = Hash[array.map.with_index{ |e, i| [e, i] }]
hash # => {"a"=>0, "b"=>1, "c"=>2, "d"=>3, "x"=>4, "y"=>5, "z"=>6}
哈希值不需要整数,它们可以是 nil 或布尔值,我根据自己的需要使用了任何一种。我在这里使用它们来使正在发生的事情更加明显。最大的胜利是哈希允许我们以任何顺序提取内容,只需指定该顺序是什么。如果它是一个范围或一组范围,我们仍然可以按我们想要的顺序提取值。
这是一个使用单个范围的简单示例:
hash.values_at(*('a' .. 'd')) # => [0, 1, 2, 3]
hash.values_at(*('x' .. 'z')) # => [4, 5, 6]
这些是复合范围示例:
hash.values_at(*('a' .. 'c'), *('x' .. 'z')) # => [0, 1, 2, 4, 5, 6]
hash.values_at(*('x' .. 'z'), *('a' .. 'c')) # => [4, 5, 6, 0, 1, 2]
请注意,在第二个范围内,范围是相反的,并且值反映了这一点。
另请注意,范围被分解为数组。数组可以来自任何地方,只要元素与哈希中的键匹配,您就会看到返回的值与数组的顺序相同。