我如何重构两个相似的函数以减少Elixir中的代码重复?

问题描述 投票:0回答:1

我具有以下两个功能:

  defp select_previous_scheduled_price(scheduled_prices, date) do
    if length(scheduled_prices) > 1 do
      before_prices = Enum.filter(scheduled_prices, &starts_before(&1, date))

      if !Enum.empty?(before_prices) do
        hd(before_prices)
      else
        nil
      end
    else
      nil
    end
  end

  defp select_next_scheduled_price(scheduled_prices, date) do
    if length(scheduled_prices) >= 1 do
      after_prices = Enum.filter(scheduled_prices, &starts_after(&1, date))

      if !Enum.empty?(after_prices) do
        hd(after_prices)
      else
        nil
      end
    else
      nil
    end
  end

有两个区别:1.第二行的运算符(即>>=);和2.在第三行3上调用的用于过滤的函数(即&starts_before/2&starts_after/2

由于差异是运算符,而不是函数和必须同时应用局部值和参数化值的函数,因此我不确定是否要考虑或如何考虑此问题。

换句话说,我想提供这样的解决方案(仅实际起作用,而实际上不会):

  defp select_previous_scheduled_price(scheduled_prices, date) do
    select_scheduled_price(scheduled_prices, date, >, &starts_before/2)
  end

  defp select_next_scheduled_price(scheduled_prices, date) do
    select_scheduled_price(scheduled_prices, date, >=, &starts_after/2)
  end

  defp select_scheduled_price(scheduled_prices, date, meets_length_criteria, filter_criteria) do
    if meets_length_criteria(scheduled_prices, 1) do
      qualified_prices = Enum.filter(scheduled_prices, &filter_criteria(&1, date))

      if !Enum.empty?(qualified_prices) do
        hd(qualified_prices)
      else
        nil
      end
    else
      nil
    end
  end

任何想法如何使这项工作?

谢谢!

functional-programming elixir refactoring higher-order-functions extraction
1个回答
0
投票
List.first/1而不是List.first/1将首先消除嵌套hd/1的必要性。然后,我将代码拆分为较小的函数,以阐明意图。

hd/1

© www.soinside.com 2019 - 2024. All rights reserved.