我正在尝试实现表格验证的算法,但我对Ruby提供的用于处理数组和哈希的多种选择感到困惑,我需要帮助将它们放在一起。以此表为例:
| A | B | C |
-------------
| 1 | 2 | 3 |
| 1 | 2 | 4 |
| 5 | 6 | 7 |
| 1 | 1 | 3 |
我的方法应该计算特定细胞组合的出现次数。例如:
match_line([A => 1, C => 3])
结果应为2
,因为此组合同时存在于第一行和最后一行。
到目前为止我所做的是创建一个hash
变量来保存列索引,如下所示:
[A => 0, B => 1, C=> 2]
我还有一个数组列表,它包含所有上面的表行,如下所示:
[[1, 2, 3], [1, 2, 4], [5, 6, 7], [1, 1, 3]]
逻辑看起来像 - 上面的match_line
方法特定用户希望匹配其中列A中具有1
值且C列中具有3
值的行它。根据我的索引哈希,A列索引为0
,C索引为2
。现在对于数组列表中的每个数组(行),如果索引0等于1
并且索引2等于用户请求的3
,我将+1添加到计数器并继续越过另一个数组行直到我结束。
我试图将其形成代码,但我最终以一种看起来非常无效的方式结束,我有兴趣看到你的代码示例,看看Ruby可能有内在的Enumerable方法,而且我是我不知道如何让它更优雅。
答案 0 :(得分:2)
首先,您应该使用最佳可用结构来描述您的域名:
data = [[1, 2, 3], [1, 2, 4], [5, 6, 7], [1, 1, 3]]
@data_hashes = data.map do |sequence|
{ 'A' => sequence[0], 'B' => sequence[1], 'C' => sequence[2] }
end
其次,我认为你应该使用真正的哈希作为match_line的输入:
# replace match_line([A => 1, C => 3]) with
match_line({'A' => 1, 'C' => 3})
现在,您可以使用Enumerable#select
和Array#size
(或使用Keith Bennet指出的Array#count
)轻松实现
def match_line(match)
@data_hashes.count { |row|
match.all? { |match_key, match_value|
row[match_key] == match_value
}
}
end
编辑:从列名称
动态创建哈希columns = ['a', 'b', 'c']
data = [[1, 2, 3], [1, 2, 4], [5, 6, 7], [1, 1, 3]]
@data_hashes = data.map do |row|
Hash[columns.zip(row)]
end