我想通过分隔符(,(来计算字符串中项目的长度。
str = 'a,3,b,c,0'
count = str.split(',').length # => 5
str = '0'
count = str.split(',').length # => 1
除了值"0"之外,如何计算?输出应该是4而不是5。或者0而不是1。
谢谢。
更新
感谢所有回复。我都试过了,效果很好!
从接收者的角度思考。您将split
发送到一个字符串,它将返回一个数组。然后将length
发送到该阵列:
str.split(',')
#=> ["a", "3", "b", "c", "0"]
str.split(',').length
#=> 4
因此,为了排除'0'
,您可以创建一个不包含不需要的元素的数组,并在该数组上调用length
:(例如,通过difference
(
str.split(',').difference(['0'])
#=> ["a", "3", "b", "c"]
str.split(',').difference(['0']).length
#=> 4
或者您可以调用count
并指定只计数非'0'
:的元素
str.split(',').count { |x| x != "0" }
#=> 4
你可以试试这个
str = 'a,3,b,c,0'
count = (str.split(',') - ['0']).length # => 4
str = '0'
count = (str.split(',') - ['0']).length # => 0
只需删除要忽略的元素:
count = str.split(',').reject {|c| c=='0'}.length
您可以保持代码的原样,但只需在拆分字符串之前删除零:
'a,3,b,c,0'.tr('0', '').split(',').length # 4
'0'.tr('0', '').split(',').length # 0
'a,3,10,b,c,0'.tr('0', '').split(',').length # 5
'0,0'.tr('0', '').split(',').length # 0
可以直接对字符串进行操作,避免了对临时数组的需要,例如通过逗号分隔字符串创建的数组。
def countem(str)
str.gsub(/(?<![^,])(?=0*[1-9])/).count
end
puts countem "1,2,0,3,0,45"
#=> 4
puts countem "00,1,2,000,45,0"
#=> 3
步骤如下。
str = "00,1,2,000,45,0"
r = /(?<![^,])(?=0*[1-9])/
正则表达式引擎维护一个指针,该指针是字符串中的当前位置。该位置位于字符串的开头或末尾,或者位于两个连续字符之间。
(?<![^,])
是一个否定的lookbedhind,它断言当前位置前面没有逗号以外的字符;也就是说,当前位置在字符串的开头,或者前面的字符是逗号。
(?=0*[1-9])/
是一个正向前瞻,它断言当前位置后面跟着零或多个零,后面跟着一个不是零的数字。也就是说,它断言当前位置后面跟着一系列不全是零的数字。
正则表达式在三个位置匹配str
持有的字符串:在,
和1
之间,在,
和2
之间,以及在,
和45
之间。每个匹配项都是一个空字符串。
enum = str.gsub(r) #=> #<Enumerator:0x00562f74d24a98>
如String#gsub的文档所示,gsub
返回一个枚举器,该枚举器生成其参数的匹配项,这里是一个正则表达式,而这里没有提供块。在这种情况下,该方法失去了用其他字符串替换字符串的意义。
通过将enum
转换为数组,我们可以看到它将生成的元素。
enum.to_a
#=> ["", "", ""]
最后,
enum.count
#=> 3