【问题标题】:Clojure - blend of "get" and "nth"?Clojure - “get”和“nth”的混合?
【发布时间】:2020-03-04 00:12:44
【问题描述】:

我正在努力寻找一个能在 get 函数和 nth 之间找到快乐媒介的函数。我一直在对这些序列类型函数进行大量研究,有没有人知道解决这个问题或知道这样执行的函数?

我需要 nth 抓取子列表的能力:

=> (nth '(1 (2 3) 4 5) 1)
(2 3)
=> (get 1 '(1 (2 3) 4 5))
nil

而且我需要 get 能够在超出范围时返回“nil”:

=> (get -1 '(1 (2 3) 4 5))
nil
=> (nth '(1 (2 3) 4 5) -1)
Execution error (IndexOutOfBoundsException) at user/eval149 (REPL:1).
null

我需要此代码用于递归子序列函数:

(defn sub-seq [coll i j]
  (nth coll i)
  (if (< i (+ i j))
    (sub-seq coll (inc' i) j)
  )
)

(sub-seq 函数应该返回从位置 'i' 开始的 'j' 个元素。)

以下是我正在尝试编写的一些示例输出:

=> (sub-seq '(1 2 (3 4) (5 (6 7))) 1 2))
(2 (3 4))
=> (sub-seq '(1 2 3 4 5 6 7) 2 4)
(3 4 5 6)

终于让我的功能正常工作了,谢谢大家的帮助:

(defn sub-seq [coll i j]
  (conj
    (list*
      (nth coll i nil)
      (if (> j 1)
        (sub-seq coll (+ i 1) (- j 1))))))

【问题讨论】:

  • 为什么要在索引超出范围时返回nil?似乎应该有更好的选择。
  • 我想通过在输出中显示 x 个超​​出范围的 x 个单位的 nil x 次来通知用户他们的输入超出了范围。

标签: recursion clojure set


【解决方案1】:

nth 采用可选的第三个参数not-found。如果您的索引超出范围,您可以使用它来提供默认值:

user=> (nth '(1 (2 3) 4 5) -1)
Execution error (IndexOutOfBoundsException) at user/eval1 (REPL:1).
null
user=> (nth '(1 (2 3) 4 5) -1 nil)
nil

如果你有向量,你可以直接使用subvec:

(let [s [1 2 3 4 5 6 7]]
  (subvec s 2 6))

如果你有一个序列,那么你可以写:

(defn subsequence [coll start n]
  (->> coll
       (drop start)
       (take n)))

(subsequence '(1 2 (3 4) (5 (6 7))) 1 2)
=> (2 (3 4))
(subsequence '(1 2 3 4 5 6 7) 2 4)
=> (3 4 5 6)

旁注:在编写 Clojure 程序时,通常可以通过序列处理更简单地解决问题。有时递归算法是必要的,但通常您可以使用 Clojure 对序列进行操作的丰富函数集。

【讨论】:

  • 刚刚在帖子中添加了一些示例输出。感谢您的回复。
【解决方案2】:

你误会get。它适用于地图和矢量等关联集合。考虑:

(ns tst.demo.core
  (:use tupelo.core tupelo.test))

(dotest
  (let [data-list '(1 (2 3) 4 5)
        data-vec (vec data-list) ]
    (spyx (nth data-list 1))
    (spyx (nth data-vec 1))
    (spyx (get data-list 1))
    (spyx (get data-vec 1))
    ))

结果

(nth data-list 1)  => (2 3)
(nth data-vec 1)   => (2 3)
(get data-list 1)  => nil
(get data-vec 1)   => (2 3)

由于 Clojure 列表不像地图那样具有关联性,list 根本不应该与列表一起使用。理想情况下,get 在传递一个列表参数时会抛出异常,表明它不适用于它们。


对于您的特定目标,也许只需执行以下操作:

(take j
  (drop i coll))

如需更多文档,请review here。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-08
    • 2012-02-10
    • 1970-01-01
    • 1970-01-01
    • 2012-01-21
    • 1970-01-01
    • 2023-03-16
    • 2014-10-17
    相关资源
    最近更新 更多