为什么在这里使用lambda而不是两个预定义的方法?

时间:2009-09-13 04:49:18

标签: ruby lambda

def divideset(rows, column, value)
split_function = nil

if value.is_a?(Fixnum) || value.is_a?(Float)
  split_function = lambda{|row| row[column] >= value}
else
  split_function = lambda{|row| row[column] == value}
end

set1 = rows.select{|row| split_function.call(row)}
set2 = rows.reject{|row| split_function.call(row)}
[set1, set2]
end

treepredict的代码中,为什么要使用lambdas?

似乎代替调用split_function.call(row),作者可以预定义两种不同的方法来处理if / else语句的两个条件 - 一个用于row[column] >= value的情况,另一个用于row[column] == value {{1}}

的情况

使用lambda是否还有其他优势?

4 个答案:

答案 0 :(得分:3)

在这种情况下使用lambdas没有额外的技术优势。

考虑一下你的建议:

def split_function_default(row, column, value)
  row[column] == value
end

def split_function_number(row, column, value)
  row[column] >= value
end

def divideset(rows, column, value)
  set1 = nil
  set2 = nil
  if value.is_a?(Fixnum) || value.is_a?(Float)
    set1 = rows.select{|row| split_function_number(row, column, value)}
    set2 = rows.reject{|row| split_function_number(row, column, value)}
  elif
    set1 = rows.select{|row| split_function_default(row, column, value)}
    set2 = rows.reject{|row| split_function_default(row, column, value)}
  end
  [set1, set2]
end

哪个更清楚?就个人而言,我更喜欢lambda版本,因为它更简洁。

答案 1 :(得分:2)

您可以预先定义这两个函数,然后使用它们。

但是在这种情况下使用lambda非常清楚,因为它们实际上是trival函数,它们的范围仅限于divideset。如果某些其他功能也会使用某些功能,最好使用预定义功能来遵循DRY原则。

答案 2 :(得分:1)

只是为了记录而进入。

split_function = lambda {|row| do_stuff_with(row) }

// don't do this
rows.select{|row| split_function.call(row)}

// do this
rows.select(&split_function)

答案 3 :(得分:0)

从某种意义上说,它只是风格,但每一点点都有帮助

虽然在一个视图中它只是风格,但在另一个视图中它确实显示了一种功能语言的功能,可以用较少的工作来完成相同数量的工作。如果我们不关心冗长和笨拙,我们可以用Java编写所有内容......

以下是一些相当轻微的“风格”变化:

def divideset(rows, column, value)
  split_function = value.is_a?(Fixnum) || value.is_a?(Float) ?
      lambda {|row| row[column] >= value} :
      lambda {|row| row[column] == value}

  [ rows.select{|row| split_function.call(row)},
    rows.reject{|row| split_function.call(row)} ]
end

def divideset(rows, column, value)
  split_function =
    if value.is_a?(Fixnum) || value.is_a?(Float) 
      lambda {|row| row[column] >= value} 
    else
      lambda {|row| row[column] == value}
    end

  [ rows.select{|row| split_function.call(row)},
    rows.reject{|row| split_function.call(row)} ]
end

也许我一直在玩too much code-golf

相关问题