Vector Clojure重排与向量的向量映射
情况是这样的:我有一个向量向量(“数据”)、一组标题、标题子集(“主要标题”)、一个常量(“C”)、一个元素函数(“f”)和其余标题(“次要标题”)。我的目标是获取“数据”并生成一个新的向量向量 示例数据: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
[[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只返回默认值