一次对两个变量运行方法

时间:2017-02-13 01:25:40

标签: ruby

我想知道除了运行两次之外,重构这段代码的正确方法是什么。

class Hamming
  def compute (a, b)

    a.to_a.split("")
    b.to_a.split("")

  end
end

是否有类似于一次分配两个变量的东西 a, b = 1, 2

2 个答案:

答案 0 :(得分:2)

首先,您的代码无效。 #to_a返回一个数组; #split未在数组上定义。

其次,如果您的代码 有效(例如,a.to_s.split(""); b.to_s.split(""),那么它实际上 实际上并不多,因为您的代码只会返回值最后执行的语句(b.to_s.split(""))。#to_s#split都是非破坏性的,这意味着它们不会更改ab - 这是唯一的影响从这个函数得到它返回的内容,并且你不会以任何方式返回a.to_s.split("")的结果:它被遗忘了。

如果你的意思是这样的话:

class Hamming
  def compute(a, b)
    [
      a.to_s.split(""),
      b.to_s.split("")
    ]
  end
end

这是相当可读的。但是,如果您的操作比.to_s.split("")更复杂,那么将它隔离到自己的函数中会更好:

class Hamming
  def compute(a, b)
    [
      list_chars(a),
      list_chars(b)
    ]
  end
  private def list_chars(str)
    str.to_s.split("")
  end
end

你可以使用map进一步简化它,但是当你有多个元素时它才真正变得必要,因为双元素的情况是完全清晰的。但是,这里有:

class Hamming
  def compute(a, b)
    [a, b].map { |x| list_chars(x) }
  end
  private def list_chars(str)
    str.to_s.split("")
  end
end

此外,您可能希望查看方法#each_char,为您提供一个迭代器,它比.split("")更具可读性,通常是更正确的选择。

编辑:在考虑了一下后,似乎你正在开始一种方法来评估两个弦之间的汉明距离;并且您不打算让该函数只返回两个字符串的字符。在这种情况下,我只是写下这个:

def compute(a, b)
  a_chars = a.to_s.each_char
  b_chars = b.to_s.each_char
  # ...
end

或者可能这样,如果你自己绝对需要字符,而不是迭代器:

def compute(a, b)
  a_chars = a.to_s.each_char.to_a
  b_chars = b.to_s.each_char.to_a
  # ...
end

我认为你正在寻找的解决方案看起来像这样:

def compute(a, b)
  a_chars, b_chars = *[a, b].map { |x| x.to_s.each_char.to_a }
  # ...
end

但我认为其可读性低于非DRY的可读性;如果你真的想要干涸它,如上所述将listification提取到它自己的函数中,并且只做

a_chars = list_chars(a)
b_chars = list_chars(b)

这实际上是两个世界中最好的,即使在这种情况下它有点过分:它是干的可维护和自我记录清晰,在冗长的情况下进行一些权衡。

答案 1 :(得分:1)

由于代码没有意义,我认为你所问的是你如何避免重复自己。

简单,编写另一种方法并调用它。这是一个想要找出哪个短语更长,但你想忽略大量空白的例子。因此foo bar不长于12345678

def longer_phrase(phraseA, phraseB)
    normalizedA = normalize(phraseA)
    normalizedB = normalize(phraseB)

    return normalizedA.length > normalizedB.length ? phraseA : phraseB
end

def normalize(phrase)
    normalized = phrase.gsub(/\s+/, ' ');
    normalized.strip!

    return normalized
end

puts longer_phrase("foo          bar  ", "12345678")

在开始工作之前,需要对所有数据进行规范化,这需要很多。这可以避免重复自己。它使您的代码更容易理解,因为我们知道所有工作的重点是规范化字符串。它为您提供了在其他地方使用的规范化功能,因此您可以以相同的方式对数据进行规范化。