data = { 'group1' => [1, nil, '3', 4.5, 'five'], 'group2' => [true, false, 6, nil, '7'] }
cleaned_data = data.transform_values do |values|
values.select do |value|
!value.nil? &&!value.is_a?(TrueClass) &&!value.is_a?(FalseClass)
end.map do |value|
if value.is_a?(String) && value.match?(/\A[+-]?\d+(\.\d+)?\z/)
value.to_f
else
value
end
end
end
puts cleaned_data
使用的方法及其优势
transform_values
:该方法遍历哈希中的每个值,并对其应用给定的块。这是一种简洁且功能强大的方式来对哈希中的所有值进行转换,保持了代码的可读性和紧凑性。
select
:用于从数组中过滤掉不需要的元素(nil
和布尔值)。这种方法能够高效地移除不需要的元素,且逻辑清晰。
map
:在过滤后的数组上,通过 map
方法对每个元素进行检查,如果是字符串类型的数字,则将其转换为实际数字类型(to_f
方法)。这确保了数据类型的一致性,方便后续处理。
性能优化
- 减少中间数组的生成:在
select
和 map
的链式调用中,尽量避免创建过多的中间数组,以减少内存的使用和性能开销。
- 使用合适的检查方法:
match?
方法用于字符串匹配数字模式,这种方式比简单的 String#to_i
或 String#to_f
更能准确判断字符串是否为数字,避免了将非数字字符串转换为 0 等错误情况。同时,is_a?
方法检查对象类型,比 instance_of?
更灵活且性能相当。