Зачем здесь использовать лямбду вместо двух предопределенных методов? - PullRequest
2 голосов
/ 13 сентября 2009
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 зачем использовать лямбды?

Кажется, что вместо вызова split_function.call(row) автор мог бы предопределить два разных метода для обработки двух условий оператора if / else - один для случая, когда row[column] >= value, и другой для случая, где row[column] == value

Есть ли здесь дополнительное преимущество от использования лямбды?

Ответы [ 4 ]

3 голосов
/ 13 сентября 2009

В этом случае нет дополнительных технических преимуществ использования лямбд.

Рассмотрим ваше предложение:

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

Что более понятно? Лично я предпочитаю лямбда-версию, поскольку она более лаконична.

2 голосов
/ 13 сентября 2009

Вы можете предварительно определить эти 2 функции, а затем использовать их.

Но использование лямбды в этом случае очень понятно, поскольку это действительно тривальные функции, и их область действия ограничена только в пределах divideset Если некоторые другие функции также будут использовать некоторые функции, лучше использовать предопределенную функцию, чтобы следовать принципу СУХОЙ.

1 голос
/ 13 сентября 2009

Просто звоните, для записи.

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)
0 голосов
/ 13 сентября 2009

В некотором смысле это просто стиль, но каждый немного помогает

Хотя в одном виде это просто стиль, в другом он показывает способность функционального языка выполнять тот же объем работы с меньшими затратами труда. Если бы мы не заботились о многословии и грубости, мы могли бы просто написать все на 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

Возможно, я играл в слишком много кода-гольфа .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...