是否有任何方法可以在cond
块中的条件中包含多个绑定表达式,类似于:
cond do
a = 1; a * 2 == 2 -> "Yes"
end
? 我想如果在Elixir中有某些东西可以成为可能,那就是"让..."绑定表达式,如Haskell:
let a = 1 in a * 2
更新
在下面的例子中,我想将String.replace
表达式绑定到变量以提高可读性(我当然可以在cond
之外进行,这不是明显的最佳解决方案原因)。条件检查input
是否仅为大写(除了非字母字符)并且来自exercism.io挑战:
String.upcase(String.replace(input, ~r/[^A-Za-z]/, "")) == String.replace(input, ~r/[^A-Za-z]/, "") and String.length(String.replace(input, ~r/[^A-Za-z]/, "")) > 0 -> "Whoa, chill out!"
答案 0 :(得分:4)
要直接回答第一个问题,答案是肯定的。您的原始代码:
cond do
a = 1; a * 2 == 2 -> "Yes"
end
解析为:
cond do
a = 1
a * 2 == 2 -> "Yes"
end
因为;
表示整个表达式的结束。如果您想要包含多个表达式,请使用parens:
cond do
(a = 1; a * 2 == 2) -> "Yes"
end
答案 1 :(得分:3)
关于你原来的问题,我认为在这里提取变量并没有错:
def myfun(input) do
sanitized = String.replace(input, ~r/[^A-Za-z]/, "")
cond do
String.upcase(sanitized) == sanitized and String.length(sanitized) > 0 -> "Whoa, chill out!"
true -> "Good job"
end
end
您也可以在模式中使用匹配运算符=
,更具体地说,您可以使用它来代替第一次出现,但我认为它更难以阅读:
def myfun(input) do
cond do
String.upcase(sanitized = String.replace(input, ~r/[^A-Za-z]/, "")) == sanitized and String.length(sanitized) > 0 -> "Whoa, chill out!"
true -> "Good job"
end
end
但是,通过仔细查看您正在进行的比较,可以改进您的代码。要匹配条件,input
字符串必须仅包含大写和非字母字符,并且至少包含一个大写字符。由于您已经在使用正则表达式,因此可以在一次检查中匹配所有这些:
\A[^a-z]*[A-Z][^a-z]*\z
说明:
\A
和\z
匹配字符串边界,整个字符串必须满足条件[^a-z]*
零个或多个非小写字符,后跟[A-Z]
字符串中的某个大写字符,后跟[^a-z]*
零个或多个非小写字符代码:
def myfun(input) do
cond do
Regex.match?(~r/\A[^a-z]*[A-Z][^a-z]*\z/, input) -> "Whoa, chill out!"
true -> "Good job"
end
end