Vector Clojure重排与向量的向量映射

Vector Clojure重排与向量的向量映射,vector,clojure,Vector,Clojure,情况是这样的:我有一个向量向量(“数据”)、一组标题、标题子集(“主要标题”)、一个常量(“C”)、一个元素函数(“f”)和其余标题(“次要标题”)。我的目标是获取“数据”并生成一个新的向量向量 示例数据: [[1.0 "A" 2.0] [1.0 "B" 4.0]] 标题示例: ["o1" "i1" "i2"] 主标题示例: ["i1" "i2"] ["o1"] 二级标题示例: ["i1" "i2"] ["o1"] 向量的新向量示例: [[(f "A") (f 2.0) C

情况是这样的:我有一个向量向量(“数据”)、一组标题、标题子集(“主要标题”)、一个常量(“C”)、一个元素函数(“f”)和其余标题(“次要标题”)。我的目标是获取“数据”并生成一个新的向量向量

示例数据:

[[1.0 "A" 2.0]
[1.0 "B" 4.0]]
标题示例:

["o1" "i1" "i2"]
主标题示例:

 ["i1" "i2"]
 ["o1"]
二级标题示例:

 ["i1" "i2"]
 ["o1"]
向量的新向量示例:

[[(f "A") (f 2.0) C (f 1.0)]
[(f "B") (f 4.0) C (f 1.0)]]
我当前的尝试是映射每一行,然后映射索引的每个元素以检查主成员身份,然后映射常量,然后映射索引的每个元素以检查辅助成员身份,最后结合结果。但我没有让它正常工作

示例代码:

(mapv (fn [row] (conj (vec (flatten (map-indexed
                                    (fn [idx item] (let [header-name (nth headers idx)] 
                                                        (if (= (some #{header-name} primary-headers) headers-name) (f item))))
                                    row)))

                  C
                  (vec (flatten (map-indexed
                                    (fn [idx item] (let [header-name (nth headers idx)] 
                                                        (if (= (some #{header-name} secondary-headers) headers-name) (f item))))
                                    row)))))
 data)

我不确定你的问题是否正确,但看起来你想要这样的东西:

(defn magic [data h p s f]
  (let [idx (map (into {} (map-indexed #(vector %2 %1) h))
                 (concat p s))]
    (mapv #(mapv (comp f (partial get %))
                 idx)
          data)))
下面是我的
magic
函数的一个示例:

(magic [[1.0 "A" 2.0]
        [1.0 "B" 4.0]]
       ["o1" "i1" "i2"]
       ["i1" "i2"]
       ["o1"]
       #(str "<" % ">"))

[["<A>" "<2.0>" "<1.0>"]
 ["<B>" "<4.0>" "<1.0>"]]
(defn magic2 [data h p s f c]
  (let [idx (getPermutation h (concat p [nil] s))]
    (permutate idx (mmap f data) c)))
这里的每个函数都是原子函数(即执行单个任务),它们都可以轻松地组合起来,精确地完成
magic
函数的功能:

(defn magic [data h p s f]
  (let [idx (getPermutation h (concat p s))]
    (->> data
         (permutate idx)
         (mmap f))))
getPermutation
函数在此计算
idx
permutation索引向量

permutate
根据给定的
idx
向量重新排列矩阵的列
data

mmap
将函数
f
应用于矩阵
数据的每个元素

更新2 上次我错过了关于添加常数的部分。因此,为了做到这一点,我们需要修改一些代码。让我们更改
permutate
函数,允许它向矩阵插入新值

(defn permutate [idx data & [default-val]]
  (mapv #(mapv (partial get %) idx (repeat default-val))
        data)))
现在,如果无法获取具有指定索引的元素,它将使用
defaultval

我们还需要一个新的
magic
函数:

(magic [[1.0 "A" 2.0]
        [1.0 "B" 4.0]]
       ["o1" "i1" "i2"]
       ["i1" "i2"]
       ["o1"]
       #(str "<" % ">"))

[["<A>" "<2.0>" "<1.0>"]
 ["<B>" "<4.0>" "<1.0>"]]
(defn magic2 [data h p s f c]
  (let [idx (getPermutation h (concat p [nil] s))]
    (permutate idx (mmap f data) c)))
我更改了应用
mmap
permutate
函数的顺序,因为您似乎不想对常量应用
f

它的工作原理是:

(magic2 [[1.0 "A" 2.0]
         [1.0 "B" 4.0]]
        ["o1" "i1" "i2"]
        ["i1" "i2"]
        ["o1"]
        #(str "<" % ">")
        "-->")

[["<A>" "<2.0>" "-->" "<1.0>"]
 ["<B>" "<4.0>" "-->" "<1.0>"]]
(magic2[[1.0“A”2.0]
[1.0“B”4.0]]
[“o1”“i1”“i2”]
[“i1”“i2”]
[“o1”]
#(str“”)
"-->")
[["" "" "-->" ""]
["" "" "-->" ""]]

我不确定你的问题是否正确,但看起来你想要这样的东西:

(defn magic [data h p s f]
  (let [idx (map (into {} (map-indexed #(vector %2 %1) h))
                 (concat p s))]
    (mapv #(mapv (comp f (partial get %))
                 idx)
          data)))
下面是我的
magic
函数的一个示例:

(magic [[1.0 "A" 2.0]
        [1.0 "B" 4.0]]
       ["o1" "i1" "i2"]
       ["i1" "i2"]
       ["o1"]
       #(str "<" % ">"))

[["<A>" "<2.0>" "<1.0>"]
 ["<B>" "<4.0>" "<1.0>"]]
(defn magic2 [data h p s f c]
  (let [idx (getPermutation h (concat p [nil] s))]
    (permutate idx (mmap f data) c)))
这里的每个函数都是原子函数(即执行单个任务),它们都可以轻松地组合起来,精确地完成
magic
函数的功能:

(defn magic [data h p s f]
  (let [idx (getPermutation h (concat p s))]
    (->> data
         (permutate idx)
         (mmap f))))
getPermutation
函数在此计算
idx
permutation索引向量

permutate
根据给定的
idx
向量重新排列矩阵的列
data

mmap
将函数
f
应用于矩阵
数据的每个元素

更新2 上次我错过了关于添加常数的部分。因此,为了做到这一点,我们需要修改一些代码。让我们更改
permutate
函数,允许它向矩阵插入新值

(defn permutate [idx data & [default-val]]
  (mapv #(mapv (partial get %) idx (repeat default-val))
        data)))
现在,如果无法获取具有指定索引的元素,它将使用
defaultval

我们还需要一个新的
magic
函数:

(magic [[1.0 "A" 2.0]
        [1.0 "B" 4.0]]
       ["o1" "i1" "i2"]
       ["i1" "i2"]
       ["o1"]
       #(str "<" % ">"))

[["<A>" "<2.0>" "<1.0>"]
 ["<B>" "<4.0>" "<1.0>"]]
(defn magic2 [data h p s f c]
  (let [idx (getPermutation h (concat p [nil] s))]
    (permutate idx (mmap f data) c)))
我更改了应用
mmap
permutate
函数的顺序,因为您似乎不想对常量应用
f

它的工作原理是:

(magic2 [[1.0 "A" 2.0]
         [1.0 "B" 4.0]]
        ["o1" "i1" "i2"]
        ["i1" "i2"]
        ["o1"]
        #(str "<" % ">")
        "-->")

[["<A>" "<2.0>" "-->" "<1.0>"]
 ["<B>" "<4.0>" "-->" "<1.0>"]]
(magic2[[1.0“A”2.0]
[1.0“B”4.0]]
[“o1”“i1”“i2”]
[“i1”“i2”]
[“o1”]
#(str“”)
"-->")
[["" "" "-->" ""]
["" "" "-->" ""]]
给定

(def data [[1.0 "A" 2.0] [1.0 "B" 4.0]])
(def headers ["o1" "i1" "i2"])
(def primaries ["i1" "i2"])
(def secondaries ["o1"])

(defn invert-sequence [s] (into {} (map-indexed (fn [i x] [x i]) s)))
。。。这就是工作:

(defn produce [hs ps ss f data const]
  (let [perms (map #(mapv (invert-sequence hs) %) [ps ss])]
    (mapv (fn [v] (->> perms
                       (map #(map (comp f v) %))
                       (interpose [const])
                       (apply concat)
                       vec))
          data)))
使用问题中的示例:

(produce headers primaries secondaries #(list 'f %) data 'C)
; [[(f "A") (f 2.0) C (f 1.0)] [(f "B") (f 4.0) C (f 1.0)]]
以Leonid Beschastny为例:

(produce headers primaries secondaries #(str "<" % ">") data 'C)
; [["<A>" "<2.0>" C "<1.0>"] ["<B>" "<4.0>" C "<1.0>"]]
使用
标识

(produce headers primaries secondaries identity data 'C)
; [["A" 2.0 C 1.0] ["B" 4.0 C 1.0]]
给定

。。。这就是工作:

(defn produce [hs ps ss f data const]
  (let [perms (map #(mapv (invert-sequence hs) %) [ps ss])]
    (mapv (fn [v] (->> perms
                       (map #(map (comp f v) %))
                       (interpose [const])
                       (apply concat)
                       vec))
          data)))
使用问题中的示例:

(produce headers primaries secondaries #(list 'f %) data 'C)
; [[(f "A") (f 2.0) C (f 1.0)] [(f "B") (f 4.0) C (f 1.0)]]
以Leonid Beschastny为例:

(produce headers primaries secondaries #(str "<" % ">") data 'C)
; [["<A>" "<2.0>" C "<1.0>"] ["<B>" "<4.0>" C "<1.0>"]]
使用
标识

(produce headers primaries secondaries identity data 'C)
; [["A" 2.0 C 1.0] ["B" 4.0 C 1.0]]
你应该考虑使用这样的东西。它是Clojure中多维数组编程的一个非常灵活的工具

大多数数组操作可能是1-2行操作

(def DATA [[1.0 "A" 2.0]
           [1.0 "B" 4.0]])

(emap (partial str "f:") (transpose (mapv #(get-column DATA %) [1 0 2])))
=> [["f:A" "f:1.0" "f:2.0"] 
    ["f:B" "f:1.0" "f:4.0"]]

你可能需要查找列名来计算<代码> [1 0 2 ] < /C>向量,但希望这能给你一个好主意,如何做到这一点。

< P>你应该考虑使用这样的东西。它是Clojure中多维数组编程的一个非常灵活的工具

大多数数组操作可能是1-2行操作

(def DATA [[1.0 "A" 2.0]
           [1.0 "B" 4.0]])

(emap (partial str "f:") (transpose (mapv #(get-column DATA %) [1 0 2])))
=> [["f:A" "f:1.0" "f:2.0"] 
    ["f:B" "f:1.0" "f:4.0"]]

您可能需要查找列名来计算
[1 0 2]
向量,但希望这能给您一个很好的方法….

如果您发布到目前为止的代码,这会有所帮助。@Arthurlfeldt补充道。如果您发布到目前为止的代码,这会有所帮助。@Arthurlfeldt补充道。我仍然需要测试一下,但是常数C是从哪里加进去的,在p和s之间?如果这个方法有效,我很兴奋,因为它使用了我不熟悉的函数。看起来我错过了常数的部分。@user1559027我用添加常数的技巧更新了我的答案。我很快就能让你的解决方案起作用了。我唯一的问题是,尽管getPermutation和mmap工作正常,但permutate只返回默认值。这是我第一次开始工作,经过了相当多的修改。你和@缩略图都很有教育意义。在传递
f
和处理结果时,我必须适应一些额外的步骤,但我已经解决了这些步骤。我仍然需要测试这些步骤,但是在p和s之间,常数C是从哪里加进来的?如果这个方法有效,我很兴奋,因为它使用了我不熟悉的函数。看起来我错过了常数的部分。@user1559027我用添加常数的技巧更新了我的答案。我很快就能让你的解决方案起作用了。我唯一的问题是,permutate只返回默认值