根据部分已知值检查数组内容的干净 Rubyist 方法是什么?

问题描述 投票:0回答:2

我有一个 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 数字] 或“无”)

感谢任何帮助。

regex ruby include pattern-matching
2个回答
2
投票

虽然“查找模式”仍处于试验阶段,但您的用例非常适合模式匹配

例如:

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'只需将此值用作模式的一部分'”


1
投票

据我所知,问题如下,“给定一个包含双元素数组的数组,确定它的至少一个元素是否使得它的第一个元素等于给定的双元素数组并且它的第二个元素等于 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
© www.soinside.com 2019 - 2024. All rights reserved.