【问题标题】:Interleaving vector elements with corresponding lists to create new vector of vectors将向量元素与相应的列表交错以创建新的向量向量
【发布时间】:2014-04-03 03:47:41
【问题描述】:

我有以下格式的数据:

[["i1" "i2"]
 ['("A" "B" "C" "D") '("red" "blue" "green" "yellow")]]

我想把它转换成一个新的数据结构:

[["column" "value"]
 ["i1" "A"]
 ["i1" "B"]
 ["i1" "C"]
 ["i1" "D"]
 ["i2" "red"]
 ["i2" "blue"]
 ["i2" "green"]
 ["i2" "yellow"]]

对于这个难题的任何帮助都会很棒。

到目前为止,我的尝试涉及使用嵌套的“for”语句,但我无法获得与标题向量相同级别的结果向量,尽管多次尝试转换结果。我还在列的值上使用了“交错”和“重复”,但这也会在错误的级别创建列表。

【问题讨论】:

  • 如果您自己尝试过,人们会更加感激并愿意为您提供更多帮助并分享您尝试过的内容
  • 你必须这样引用列表:['("A" "B" "C" "D") '("red" "blue" "green" "yellow")]]
  • @shaktimaan 谢谢。我添加了信息。
  • @Thumbnail 谢谢,这是我的一个常见错误。

标签: list vector clojure


【解决方案1】:
(defn doit [[is vss]]
  (vec (cons
         ["column" "value"]
         (mapcat (fn [i vs] (mapv (fn [v] [i v]) vs)) is vss))))

【讨论】:

  • 已更正。以前的错误版本相当正确地被否决了。
【解决方案2】:
(defn convert
  [[header data]]
  (->> (mapcat #(map vector (repeat %) %2) header data)
       (cons ["column" "value"])))

(convert '[["i1" "i2"] [("A" "B" "C" "D") ("red" "blue" "green" "yellow")]])
;; => (["column" "value"] 
;;     ["i1" "A"] ["i1" "B"] ["i1" "C"] ["i1" "D"] 
;;     ["i2" "red"] ["i2" "blue"] ["i2" "green"] ["i2" "yellow"])

【讨论】:

    【解决方案3】:
    (defn conform
      [[ks & rows]]
      (mapcat
       (fn [row]
         (mapcat (fn [k val]
                   (map (partial vector k) val))
                 ks row))
       rows))
    

    你的例子:

    (conform [["i1" "i2"] ['("A" "B" "C" "D") '("red" "blue" "green" "yellow")]])
    => (["i1" "A"] ["i1" "B"] ["i1" "C"] ["i1" "D"]
        ["i2" "red"] ["i2" "blue"] ["i2" "green"] ["i2" "yellow"])
    

    奖金:

    (conform [["i1" "i2"]
              ['("A" "B" "C" "D") '("red" "blue" "green" "yellow")]
              ['("E" "F" "G" "H") '("Mara" "Lara" "Clara" "Foxy")]])
    
    => (["i1" "A"] ["i1" "B"] ["i1" "C"] ["i1" "D"] 
        ["i2" "red"] ["i2" "blue"] ["i2" "green"] ["i2" "yellow"] 
        ["i1" "E"] ["i1" "F"] ["i1" "G"] ["i1" "H"] 
        ["i2" "Mara"] ["i2" "Lara"] ["i2" "Clara"] ["i2" "Foxy"])
    

    更多奖励:

    (conform [["i1" "i2" "i3"]
              ['("A" "B" "C" "D") '("red" "blue" "green" "yellow") ["Ufo"]]
              ['("E" "F" "G" "H") '("Mara" "Lara" "Clara" "Foxy") ["Orange" "Apple"]]])
    
    => (["i1" "A"] ["i1" "B"] ["i1" "C"] ["i1" "D"] 
        ["i2" "red"] ["i2" "blue"] ["i2" "green"] ["i2" "yellow"] 
        ["i3" "Ufo"] 
        ["i1" "E"] ["i1" "F"] ["i1" "G"] ["i1" "H"] 
        ["i2" "Mara"] ["i2" "Lara"] ["i2" "Clara"] ["i2" "Foxy"] ["i3" "Orange"] ["i3" "Apple"])
    

    根据结果创建地图很容易:

    (reduce (fn [acc [k v]]
              (update-in acc [k] (fnil conj []) v)) {} *1 )
    
    => {"i3" ["Ufo" "Orange" "Apple"], 
        "i2" ["red" "blue" "green" "yellow" "Mara" "Lara" "Clara" "Foxy"], 
        "i1" ["A" "B" "C" "D" "E" "F" "G" "H"]}
    

    【讨论】:

      【解决方案4】:

      这里有一些有趣的答案。我只是从概念上补充一点,我认为这是for 的好地方。对于第一个向量中的每个项目,您希望将其与第二个向量中相应列表中的项目配对。

      (defn convert [[cols vals]]
          (vec (cons ["column" "value"] ;; turn the list into a vector.
                  (for [i (range (count cols)) ;; i <- index over columns
                        j (nth vals i)] ;; j <- items from the ith list
                    [(nth cols i) j])))) ;; [col val]
      
      user=>(convert data)
      

      这很容易修改以处理更多的值向量:

      (defn convert [[cols & vals]]
          (cons ["column" "value"]
              (mapcat #(for [i (range (count cols))
                             j (nth % i)]
                         [(nth cols i) j])
                      vals)))
      

      【讨论】:

      • 您的 for 构造错误。在j 中,您正在遍历各个单词的字母。另外,为什么要搞乱索引?
      • 另外,我使用索引是因为我们不想将cols 中的每个项目与vals 中每个列表中的项目配对,我希望for 完成大部分工作工作。为什么?因为我看到了四个答案,其中三个几乎相同,没有一个使用for。答案没有错,但我们不是来为人们编写代码的,我们是来教书的。
      • 对不起,我的错。我发誓我在我的 REPL 中尝试过,今天早上看到了不同的结果 -
      • @galdre 我要感谢您使用“for”。我尝试了很长时间才能让它工作,但不能。我认为 mapcat 和 cons 是我缺少的部分,我没有考虑过。这很有启发性。
      【解决方案5】:

      不是惯用的,但成功了。

      ((fn [coll]
         (let [ks (first coll) vs (last coll)]
           (cons 
            '("column" "value")
            (partition 2 (concat
                          (interleave (repeat (first ks)) (first vs))
                          (interleave (repeat (last ks)) (last vs)))))))
       [["i1" "i2"]
        ['("A" "B" "C" "D") '("red" "blue" "green" "yellow")]])
      

      【讨论】:

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