Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
习惯用语Clojure中的前一周编号和相应年份?_Clojure_Idioms - Fatal编程技术网

习惯用语Clojure中的前一周编号和相应年份?

习惯用语Clojure中的前一周编号和相应年份?,clojure,idioms,Clojure,Idioms,我正在学习用Clojure更地道一些。我觉得我的以下实现可以更惯用、更简单: (defn refine-previous-week-and-year [initial-year, initial-week] ;; Returns the week number and year of previous week, ;; taking consideration if the current week is 1st week of a year, ;; then the previ

我正在学习用Clojure更地道一些。我觉得我的以下实现可以更惯用、更简单:

  (defn refine-previous-week-and-year [initial-year, initial-week]
  ;; Returns the week number and year of previous week,
  ;; taking consideration if the current week is 1st week of a year,
  ;; then the previous week is the week 52 of the last year.

  ;; If the initial week number is not nil, keep it as the week number.
  ;; If the initial year number is not nil, keep it as the year number.
  ;; If the intial year is nil, return the current year, unless, the initial-week is nil,
  ;; and the previous week is the week 52 of the last year, then return last year. 
  ;; If the inital week number is nil, then the previous week number is current week minus one,
  ;; unless, the current week 1, then the previous week is 52, and the year is last year.

  (cond
    (and initial-week initial-week) [initial-year initial-week]
    (nil? initial-week) (let [previous-week-raw (- (current-week) 1)]
                          (if (= 0 previous-week-raw)
                            [(if initial-year initial-year (- (current-year) 1)) 52]
                            [(if initial-year initial-year (current-year)) previous-week-raw]))
    (nil? initial-year) [(current-year) initial-week]))
考虑输入参数是否为零存在复杂的逻辑,考虑前一周的逻辑是去年的逻辑

非常感谢你的帮助

编辑

根据评论和建议,以下是我的改进版本:

  (defn refined-previous-week-and-year
    "
    Returns the week number and year of previous week,
    taking consideration if the previous week is the last week
    (52) of the last year.

    If the raw-week number is not nil, keep it as the week number.
    If the raw-year number is not nil, keep it as the year number.

    If the raw-year is nil, return the current year,
    unless the raw-week is nil, and the previous week is the last week (52)
    of the last year, then return last year.

    If the raw-week number is nil,
    then the previous week number is current week minus one,
    unless the previous week is the last week (52) of the last year,
    and the year should be last year.
    "

    [raw-year, raw-week]

    (let [real-year-and-previous-week (memoize  (fn [] (let [previous-week-computed (dec (current-week))
                                                             year (current-year)]
                                                         (if (= 0 previous-week-computed)
                                                           {:year (dec year) :week 52}
                                                           {:year year :week previous-week-computed}))))
          real-year (fn [] (:year (real-year-and-previous-week)))
          real-previous-week (fn [] (:week (real-year-and-previous-week)))]
      {:year (or raw-year (real-year)) :week (or raw-week (real-previous-week))}))
我使用函数和memoize来计算实际年份和实际前一周。我想知道是否可以通过更简单的方法来实现

使用(或xy)表达式,逻辑更简单,我已经解决了处理原始参数为零与否的卷积,以及使用函数捕捉计算的前一周计算


非常感谢你对我学习的帮助

以下是一些规则,您可以将其应用到更加惯用的语言中:

  • 使用docstring而不是注释
  • 删除函数参数列表中的逗号。逗号在Clojure中被视为空白,通常避免使用。换行和对齐用于提供清晰度
  • 将图案(如果x y)替换为(或x y)
  • 将(-x 1)替换为(12月x日)

您的代码似乎并不像广告中所说的那样适用于所有情况,并且可以使代码变得更简单,主要是将两个输入值视为不存在时需要默认的东西。在这一点之后,过程总是一样的

(defn refine-previous-week-and-year
  "Returns the week number and year of previous week,
  taking consideration if the current week is 1st week of a year,
  then the previous week is the week 52 of the last year."
  [input-year input-week]
  (let [year (or input-year (current-year))  ; Use current year/week
        week (or input-week (current-week))] ; if none provided
    (if (= 1 week)
      [(dec year) 52]
      [year (dec week)])))

编辑:

我似乎不理解你的要求,但我认为你的评论有误导性,所以我删除了文档字符串。为了获得我认为您想要的行为,我将其分为两个更简单的函数:

(defn previous-week
  [year week]
    (if (= 1 week)
      [(dec year) 52]
      [year (dec week)]))

(defn previous-week-if-no-week
  [input-year input-week]
  (let [year (or input-year (current-year))]
    (if input-week
      [year input-week]
      (previous-week year (current-week)))))

您可以使用docstring而不是comment。另外,看看这个:谢谢你优雅的解决方案!但我意识到我希望非零输入参数根本不被修改,更接近要求。它很好地涵盖了输入周的情况:当它被设置时,就根本没有变化。我需要输入年份的相同逻辑,当设置时,不允许更改。