Elixir中cond块中条件内的绑定表达式?

时间:2014-12-06 22:14:40

标签: conditional-statements elixir

是否有任何方法可以在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!"

2 个答案:

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