在clojure中删除向量的第n个元素

时间:2016-01-26 02:26:50

标签: clojure

我正在尝试在clojure中做一个非常基本的问题,并且在向量/列表的工作方式方面遇到一些麻烦。

首先,当我定义一个以向量作为参数的函数的参数时,如何将其表示为参数。

你会把它作为单个变量说出来吗

(defn example [avector] (This is where the function goes) )

或者您是否必须事先列出矢量或列表的每个元素?

(defn example [vectorpart1 vectorpart2 vectorpart3 vectorpart4 ] (This is where the function goes) )

另外,就矢量和列表而言,是否有人知道允许您计算向量长度或获取第一个/最后一个/或第n个元素的命令?

3 个答案:

答案 0 :(得分:2)

您的第一个示例定义了一个函数,它接受一个参数,无论其类型如何。如果传递一个向量,那么该参数将被设置为向量。

(example [1 2 3 4]) ;; (= avector [1 2 3 4])

你的第二个例子定义了一个带有四个参数的函数。您需要传递四个单独的值才能使对此函数的调用有效。

(example [1] [2] [3] [4])
;; (= vectorpart1 [1])
;; (= vectorpart2 [2])
;; (= vectorpart3 [3])
;; (= vectorpart4 [4])

听起来您可能正在考虑解构语法,它允许您直接从参数向量中构造值。

(defn example [[a b c d]]
  ())

参数定义中的文字向量语法描述了第一个参数中的项与函数范围中可用的符号之间的映射。

(example [1 2 3 4])
;; (= a 1)
;; (= b 2)
;; (= c 3)
;; (= d 4)

同样位于此空间的另一个函数是apply。 Apply接受一个列表或参数向量,并在原地调用函数。

(defn example [a b c]
  (assert (= a 1))
  (assert (= b 2))
  (assert (= c 3)))

如果我们用一个向量调用此函数,你将得到一个arity异常。

(example [1 2 3])
;; ArityException Wrong number of args (1) passed ...

相反,我们可以使用apply将向量作为参数传递。

(apply example [1 2 3])
;; no errors!

您可以在Clojure文档中找到使用矢量所需的所有方法。

如果要删除特定元素,只需将元素及其后面的元素取出,然后将它们连接在一起。

(def v [1 2 3])
(concat (subvec v 0 1) (subvec v 2))

答案 1 :(得分:1)

从向量n删除索引v处的元素:

(defn remove-indexed [v n]
  (into (subvec v 0 n) (subvec v (inc n))))

例如,

(remove-indexed (vec (range 10)) 5)
;[0 1 2 3 4 6 7 8 9]

很多都可能出错:

  1. v可能不是矢量。
  2. n可能不是一个整数。
  3. n可能超出v的范围(我们需要(contains? v n)
  4. Clojure在运行时检测到所有这些错误。静态类型语言在编译时会检测到1和2但不会检测到3。

答案 2 :(得分:0)

简短的回答是你的第一个例子是正确的。你不想为你的向量的每一部分命名,因为你通常会使用不确定长度的向量。如果您想对需要分配部件的矢量执行某些操作,可以destructuring执行此操作。

稍微长一点的答案是发送到任何clojure defn 的参数列表已经是向量。请注意,参数列表使用[]来包装其args列表。这是因为在Clojure中代码和数据是一回事。来自this article ...

  

Lisps是homoiconic,意味着用该语言编写的代码被编码为该语言具有操作工具的数据结构。

这可能比您正在寻找的更多,但它是一个重要的相关概念。

这里有一个简单的示例让你前进......将一个向量(在这种情况下是字符串)传递给一个函数,它返回向量。但是,如果map超过它,它会将向量的内容连续传递给函数。

user=> (def params ["bar" "baz"])
#'user/params
user=> (defn foo [params] (println params))
#'user/foo
user=> (foo params)
[bar baz]
nil
user=> (map foo params)
bar
baz
(nil nil)

此外,请查看Clojure cheatsheet以了解有关使用向量(以及Clojure中的所有其他内容)可以执行的操作的更多信息。

相关问题