检查表

时间:2016-05-17 10:29:57

标签: ruby

我正在尝试实现表格验证的算法,但我对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方法,而且我是我不知道如何让它更优雅。

1 个答案:

答案 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#selectArray#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