我有一个 3d 数组,我需要根据部分已知值检查它的第二个“维度”。下面的数组组成说明:
a = [[[1,1], nil]], [[2,3], [4,8]], [[6,1],[9,9]], [[5,7], nil]]]
我需要检查这个数组是否存在包含两个值的数组,第一个我会知道它的确切内容,但我只知道第二个它是
nil
或2具有未知个位数值的元素数组。在伪代码中,我想做的是; a.include?([[1,1],*unknown*])
.
也许正则表达式匹配器是解决问题的方法(?)。也许像;
a.include?([[1,1],/\[\d,\d\]||(nil)])
(我想说的是;[任何单个 0-9 数字,任何单个 0-9 数字] 或“无”)
感谢任何帮助。
虽然“查找模式”仍处于试验阶段,但您的用例非常适合模式匹配
例如:
arr = [[[1,1], nil], [[2,3], [4,8]], [[6,1], [9,9]],
[[2,3], [3,7]], [[5,7], nil],[[7,9],[42,1]]]
def matches_known_pattern?(arr,known)
case arr
in [*,[^known,nil|[0..9,0..9]],*]
true
else
false
end
end
matches_known_pattern?(arr,[1,1]) #=> true
matches_known_pattern?(arr,[2,3]) #=> true
matches_known_pattern?(arr,[7,8]) #=> false
matches_known_pattern?(arr,[7,9]) #=> false because 42 does not match 0..9
matches_known_pattern?(arr,[1,'a']) #=> false
该模式相当不言自明,但它分解为
a[0] == known
和 a[1] == nil
或 a[1]
是 0 到 9 之间的任意 2 个整数的数组。如果你想允许任何整数,你可以用 替换
[0..9,0..9]
[Integer,Integer]
.
两侧的
[*,...,*]
是实验性的“查找模式”部分。本质上它只是意味着在arr
中的任何地方找到这个模式(变量绑定的第一个匹配获胜)。
另一个注释是
^known
,因为模式匹配允许在没有插入符号(^
)的情况下进行变量绑定,变量known
将被分配模式中第一个元素(a[0][0]
)的值。 ^
“固定”局部变量known
或如文档中所述“对于这种情况,可以使用固定运算符^
,告诉Ruby'只需将此值用作模式的一部分'”
据我所知,问题如下,“给定一个包含双元素数组的数组,确定它的至少一个元素是否使得它的第一个元素等于给定的双元素数组并且它的第二个元素等于 nil 或一个由两位数字组成的数组。
您可以使用以下方法来确定给定数组是否具有该属性。
def is_it_there?(arr, first_known)
arr.any? do |first,second|
first == first_known &&
(second.nil? ||
(second.is_a?(Array) && second.size == 2 &&
second.all? { |n| (0..9).cover?(n) }))
end
end
arr = [[[1,1], nil], [[2,3], [4,8]], [[6,1], 0..9], [[5,7], nil],
[[3,8], 2], [[7,6], [1,2,3], [[3,1], [1,12]], [[2,2], [-1,2]]]]
is_it_there?(arr, [2,3]) #=> true
is_it_there?(arr, [1,1]) #=> true
is_it_there?(arr, [5,7]) #=> true
is_it_there?(arr, [1,6]) #=> false
is_it_there?(arr, [3,8]) #=> false
is_it_there?(arr, [7,6]) #=> false
is_it_there?(arr, [3,1]) #=> false
is_it_there?(arr, [2,2]) #=> false
is_it_there?(arr, [6,1]) #=> false