【问题标题】:Map only selected elements in a list仅映射列表中的选定元素
【发布时间】:2020-04-19 14:51:25
【问题描述】:

假设我有一个元素列表 L、一个函数 g 和一个索引列表 I

那么,如何将函数g 仅映射到由索引I 指定的列表L 的元素?

例如,如果g 是平方函数,L 是列表(1 2 3 4 5 6 7)I 是索引集(1 3 4),那么我应该得到 (1 4 3 16 25 6 7),即列表L,我在其中对位置I 的元素进行平方。

(第一个索引为0,就像在nth函数中使用的一样)

我可以以某种方式做到这一点,但我想知道是否有一种简单的方法来做到这一点。

【问题讨论】:

标签: clojure


【解决方案1】:

或者,没有库,你可以使用map-indexed

(def I #{1 3 4})
(def L '(1 2 3 4 5 6 7))

(defn g [n] (* n n))


(map-indexed #(if (I %) (g %2) %2) L))

; or, with explicit parameters

(map-indexed (fn [i n] (if (I i) (g n) n)) L)

; Both produce a lazy-list of (1 4 3 16 25 6 7)

当然,有了更好的名字,这将更具可读性。

我在这里设置了I 而不是列表,因此可以有效地进行查找。如果您最初将其作为列表,则可以使用set 将其转换为集合。

另外请注意,这会产生一个惰性列表。如果你想要一个不同的结构,你可以使用 vec 来强制它变成一个向量。

【讨论】:

  • 包含?上单是不行的。这不只是显示,它不起作用。
  • @amalloy 哎呀。老实说,自从我编写 Clojure 以来已经有一段时间了。显然我开始失去一些基础知识。真可惜。
【解决方案2】:
(require '[com.rpl.specter :as s])
(use '[plumbing.core])
(s/transform [s/INDEXED-VALS (fn->> first (contains? #{1 3 4})) s/LAST]
             (fn [x] (* x x)) 
             '(1 2 3 4 5 6 7))

【讨论】:

    【解决方案3】:

    我想说,你可以通过一个简单的map 调用来做到这一点:

    (defn g [x]
      (* x x))
    
    (def L '(1 2 3 4 5 6 7))
    (def I '(1 3 4))
    (map #(g (nth L %)) I)
    ;; => (4 16 25)
    

    这里的思路是,对于I 的每个索引,我在L 中查找相关值,并在其上计算g 函数。

    【讨论】:

      【解决方案4】:

      另一种选择是循环更改所需的索引,使用assoc 替换向量中的项目:

      (ns tst.demo.core
        (:use tupelo.core tupelo.test) )
      
      (defn update-idx
        [data txfn idxs]
        (reduce
          (fn [result idx]
            (let [val-orig (get result idx)
                  val-new  (txfn val-orig)]
              (assoc result idx val-new)))
          (vec data) ; coerce data to vector
          idxs))
      
      (dotest
        (let [plus100 (fn [x] (+ 100 x))]
          (is= (update-idx (range 10) plus100 [2 3 5 7]))
          [0 1 102 103 4 105 6 107 8 9]))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-03
        • 1970-01-01
        • 1970-01-01
        • 2020-03-23
        相关资源
        最近更新 更多