Clojure重排和载体向量的映射 [英] Clojure rearrangement and mapping of vector of vectors

查看:116
本文介绍了Clojure重排和载体向量的映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里是情况:我有一个矢量(数据),一组头,一个头的子集(主头),常量(C),元素方面的函数f)和剩余报头(辅报头)。我的目标是采取数据,并产生一个新的向量的向量。



示例数据:

  [[1.0A2.0] 
[1.0B4.0]]

示例标题:

  [o1i1i2] 

主标题示例:

  [i1i2] 

次要标题范例:

  [o1] 

向量的新向量示例:

  [[(fA)(f 2.0)C(f 1.0)] 
[ f 1.0)]]



我当前的尝试是mapv每行,然后map-indexed每个元素一个如果检查主成员身份,然后常量,然后map-indexed每个元素用一个if检查次要成员资格,最后conj结果。

 <$ c $ 

c>(mapv(fn [row](conj(vec(flat(map-indexed
(fn [idx item](let [header-name(nth headers idx)]
一些#{header-name} primary-headers)header-name)(f item))))
row)))

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


解决方案

不知道我的问题是否正确,但看起来像这样:

  
(concat ps))] $ b $($ h) b(mapv#(mapv(comp f(partial get%))
idx)
data)))

下面是我的 magic 函数的示例:

 (magic [[1.0A2.0] 
[1.0B4.0]]
[o1i1i2]
[i1 i2]
[o1]
#(str<%>))

[[& < 2.0> < 1.0>]
[< B> < 4.0> < 1.0>]]

让我们仔细看看。

首先,我计算置换索引 idx 。在你的情况下,它是(1 2 0)。为了计算它我把 [o1i1i2] 变成散列映射 {o10, i1,i22} ,然后在(i1i2o1)



然后我使用 idx 重新排列数据基质。在这一步,我还对新的重排矩阵的每个元素应用 f 函数。



更新



我认为最好将复杂的 magic 函数分成三个更简单的函数:

 (defn getPermutation [h1 h2] 
(map(into {}(map-indexed#(vector%2%1)h1))
h2))

(defn permutate [idx data]
(mapv#(mapv(partial get%)idx)
data)))

(defn mmap [f data]
(mapv(partial mapv f)
data))

这里的每个函数都是原子的(即执行单个任务),并且它们都可以很容易地组合起来以完成 magic / p>

 (defn magic [data hpsf] 
(let [idx(getPermutation h(concat ps))]
( - >> data
(permutate idx)
(mmap f))))


b $ b

getPermutation 函数计算 idx 置换索引向量。


$根据给定的 idx 重新排列矩阵的列数据,b $ b

/ code>向量。



mmap 应用函数 f 到矩阵的每个元素 data



更新2



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

  
(mapv#(mapv(partial get%)idx(repeat default-val))
data))
/ code>

现在,它将使用 default-val t能够获得指定索引 idx 的元素。



我们还需要一个新的 magic function:

 (defn magic2 [data hpsfc] 
let [idx(getPermutation h(concat p [nil] s))]
(permutate idx(mmap f data)c)))

我改变了应用 mmap 函数的顺序,因为它似乎您不想将 f 应用于您的常数。



它的工作原理:

 (magic2 [[1.0A2.0] 
[1.0B4.0]]
[o1 i1i2]
[i1i2]
[o1]
#(str<%& - >)

[[< A> < 2.0> - > < 1.0>]
[< B> < 4.0> - > < 1.0>]]


Here is the situation: I have a vector of vectors ("data"), a set of headers, a subset of headers ("primary headers"), a constant ("C"), an element-wise function ("f"), and the remaining headers ("secondary headers"). My goal is to take the "data" and produce a new vector of vectors.

Example data:

[[1.0 "A" 2.0]
[1.0 "B" 4.0]]

Example headers:

["o1" "i1" "i2"]

Example primary headers:

 ["i1" "i2"]

Example secondary headers:

 ["o1"]

Example new vector of vectors:

[[(f "A") (f 2.0) C (f 1.0)]
[(f "B") (f 4.0) C (f 1.0)]]

My current attempt is to mapv each row, then map-indexed each element with an if to check for primary membership, then the constant, then map-indexed each element with an if to check for secondary membership, finally conj on the results. But I am not getting it to work right.

Example code:

(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)

解决方案

Not sure if I got your problem right, but looks like you want something like this:

(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)))

Here is an example of my magic function:

(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>"]]

Let's get a closer look at it.

First of all, I'm calculating permutation index idx. In your case it's (1 2 0). In order to calculate it I'm turning ["o1" "i1" "i2"] into a hash map {"o1" 0, "i1" 1, "i2" 2} and then using it on ("i1" "i2" "o1") sequence of primary and secondary headers.

Then I'm using idx to rearrange data matrix. On this step I'm also applying f function to each element of new rearranged matrix.

Update

I thought that it'll be best to split my complicated magic function into three simpler ones:

(defn getPermutation [h1 h2]
  (map (into {} (map-indexed #(vector %2 %1) h1))
       h2))

(defn permutate [idx data]
  (mapv #(mapv (partial get %) idx)
        data)))

(defn mmap [f data]
  (mapv (partial mapv f)
        data))

Each function here is atomic (i.e. performing a single task), and they all could be easily combined to do exactly what magic function do:

(defn magic [data h p s f]
  (let [idx (getPermutation h (concat p s))]
    (->> data
         (permutate idx)
         (mmap f))))

getPermutation function here calculates idx permutation index vector.

permutate rearranges columns of a matrix data according to given idx vector.

mmap applies function f to each element of a matrix data.

Update 2

Last time I missed the part about adding a constant. So, in order to do so we'll need to change some of the code. Let's change permutate function allowing it to insert new values to the matrix.

(defn permutate [idx data & [default-val]]
  (mapv #(mapv (partial get %) idx (repeat default-val))
        data)))

Now, it'll use default-val if it won't be able to get the element with the specified index idx.

We'll also need a new magic function:

(defn magic2 [data h p s f c]
  (let [idx (getPermutation h (concat p [nil] s))]
    (permutate idx (mmap f data) c)))

I changed the order of applying mmap and permutate functions because it seems that you don't want to apply f to your constant.

And it works:

(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>"]]

这篇关于Clojure重排和载体向量的映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆