【问题标题】:return vector without nth element (complement of (nth))返回没有第 n 个元素的向量(第 (nth) 的补码)
【发布时间】:2014-03-09 19:35:58
【问题描述】:

我需要从integers 的vector 中获取一个随机值。

我还需要取回没有值键的vector。

示例代码如下。我知道我可以轻松地将这段代码放在function 中以重复使用。

但是想知道是否有一些功能或更好的方法可以在没有第 n 个元素的情况下创建一个新的vector? (因此是核心 clojure 中 (nth) function 的补码)

(let [ vector [1 2 3 5 9 1]
       id (rand-int (count vector))
       value (nth vector id)
       head (take id vector)
       tail (drop (+ id 1) vector)
       vector (flatten [head tail])]
  {:value value :new-vector vector})

【问题讨论】:

    标签: function vector clojure


    【解决方案1】:

    矢量数据结构不能有效地删除单个元素。如果您经常这样做,您通常应该使用更合适的数据结构。例如,如果向量的元素是不同的,则可以使用集合(或排序集,如果在其他情况下顺序对您很重要)。或者如果它们不是不同的,但你从不关心顺序,你可以做一个Fisher-Yates shuffle - 这里我们使用一个向量,但是通过将中间的一个与元素交换来避免“从中间移除很昂贵”的问题在末尾,然后从末尾删除。

    【讨论】:

    • 一个更合适的类似于向量的数据结构是rrb-vector。切片和连接是在对数时间内完成的。
    • 我没有使用您链接到的函数,但它启发了我结合 first/rest 研究 clojure.core shuffle 函数。感谢您的洞察力!
    【解决方案2】:

    听从 @amalloy 的建议,但如果您仍想创建一个函数,您可以执行类似的操作

    (defn sans-nth [v idx]
      "Takes in a vector and an index. 
       Returns value at index and removes value from vector"
      (let [x (get @v idx)
            y #(vec (concat (take idx %) (drop (inc idx) %)))]
            (swap! v y)
            x))
    

    例子

    (def v (atom [1 2 3 4 5 6]))
    

    '用户/v

    (sans-nth v 3)
    

    4

    @v
    

    [1 2 3 5 6]

    如果您只需要从向量中删除一个元素

    (defn remove-nth [v i]
      (vec (concat (take i v) (drop (inc i) v))))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-11
      • 2012-04-05
      • 2022-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-10
      相关资源
      最近更新 更多