首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从命名参数生成两个.csv文件

从命名参数生成两个.csv文件
EN

Code Review用户
提问于 2014-02-06 07:56:03
回答 1查看 222关注 0票数 4

我编写了Clojure代码,它的名称为params,必须生成2个.csv文件作为输出。

请复习一下。

代码语言:javascript
复制
(ns my_cli_clojure.core
  (:gen-class :main true))

(require '[clojure.data.csv :as csv]
     '[clojure.java.io :as io]
     '[me.raynes.fs :as fs]
     '[clojure.tools.cli :refer [cli] :as c])

(defn write_csv_data [& {:keys [data outfile]
                     :or {data ""
                          outfile ""}}]
  (csv/write-csv outfile
                data))

(defn -main
  [& args]
    (let [[options args banner]
  (c/cli args
 ["-d" "-dome" "Dome Identifier" :default "dome1"]
 ["-p" "-principal" "Principal code" :default "kraft"]
 ["-o" "-output-directory" "Output file" :default "."]
 ["-h" "-help" "Show Help" :flag true :default false])]

(when (:help options)
  (println banner)
  (System/exit 0))

 (let [output_directory (:output-directory options)]
(if-not (fs/exists? output_directory)
  (fs/mkdirs output_directory))
(doseq [n (clojure.string/split (:dome options) #",")]
  (let [dome_identifier (first (clojure.string/split n #"-"))]
(with-open [out-file (io/writer (clojure.string/join "/" [output_directory
                                                                  (clojure.string/join "." [dome_identifier "csv"])]))]
(write_csv_data :data [["dome_identifier" "name"]
                       [dome_identifier (first (reverse     (clojure.string/split n #"-")))]] :outfile out-file))

(with-open [dome_principal_file (io/writer (clojure.string/join "/" [output_directory
                                                                           (clojure.string/join "." ["dome_principal" dome_identifier "csv"])]))]
 (write_csv_data :data [(clojure.string/split "dome_identifier principal_code currency_code active latitude longitude" #"\s")
                        [dome_identifier (:principal options) "" "t" "" ""]] :outfile dome_principal_file)))))))
EN

回答 1

Code Review用户

发布于 2014-03-18 18:20:53

总的来说,一切看起来都很不错,直到我到了(let [output_directory ...部分,然后你的压痕都变得不稳了!问题的一部分是,有几行非常长的行,当您在S表达式中嵌套这么多层时,很难保持它们的长度。以一种直观的方式缩短你的线条,并确保所有的东西从一条线到另一条线都会解决这个问题。

首先,我认为在命名空间定义中包含所有use/require/import语句是惯用的做法,如下所示:

代码语言:javascript
复制
(ns my_cli_clojure.core
  (:require [clojure.data.csv :as csv]
            [clojure.java.io :as io]
            [me.raynes.fs :as fs]
            [clojure.tools.cli :refer [cli] :as c]
            [clojure.string :as s])
  (:gen-class :main true))

注意,我添加了[clojure.string :as s] --这个缩写将有助于缩短后面的一些行,在这些行中,有许多对clojure.string方法的完全限定的引用。

接下来,在这里调整一个美学间距:

代码语言:javascript
复制
(defn write-csv-data [& {:keys [data outfile] :or {data "", outfile ""}}]
  (csv/write-csv outfile data))

您的代码很好,我只是觉得我的版本很容易读一眼。当我编写的代码在较少的行上看起来足够紧凑时,我通常尽量避免使用换行。当线开始变长时,我会更多地考虑把它们分开的最有意义的地方。(我还将write_csv_data重命名为write csv-data;它在Clojure中使用连字符而不是下划线来命名符号是惯用的)

在这里进行更多的间距调整:

代码语言:javascript
复制
(defn -main [& args]
  (let [[options args banner]
        (c/cli args
               ["-d" "-dome" "Dome Identifier" :default "dome1"]
               ["-p" "-principal" "Principal code" :default "kraft"]
               ["-o" "-output-directory" "Output file" :default "."]
               ["-h" "-help" "Show Help" :flag true :default false])]

最后,我将如何处理这个角色:

代码语言:javascript
复制
(let [out-dir (:output-directory options)]
  (if-not (fs/exists? out-dir)
    (fs/mkdirs out-dir))
  (doseq [n (s/split (:dome options) #",")]
    (let [dome-id (first (s/split n #"-"))]
      (with-open [out-file (io/writer (str out-dir "/" dome-id ".csv"))]
        (write-csv-data :data [["dome_identifier" "name"]
                               [dome-id (last (s/split n #"-"))]] 
                        :outfile out-file))
      (with-open [dome-principal-file 
                  (io/writer (str out-dir "/dome_principal." dome-id ".csv"))]
        (write-csv-data :data [["dome_identifier" "principal_code" 
                                "currency_code" "active" "latitude" "longitude"]
                               [dome-id (:principal options) "" "t" "" ""]] 
                        :outfile dome-principal-file)))))))

更改:

  1. 我缩短了几个符号名,比如output_directory => out-dir和dome_identifier => dome-id.
  2. 我用(s/join "/" [out-dir (s/join "." [dome-id "csv"])])这样的模式将这两个部分更改为(str out-dir "/" dome-id ".csv"),它更简洁,更易于阅读。保持简单!
  3. 我将(first (reverse (s/split n #"-")))简化为(last (s/split n #"-"))
  4. 在您的代码中,有一部分是通过执行如下操作来创建字符串列表的:(s/split "first-string second-string third-string fourth-string" #"\s+")。这是聪明的,但缺点是,它留给你一个长的字符串,你不能打破,以缩短你的线条。在这种情况下,我认为只键入["first-string" "second-string" "third-string" "fourth-string"]就更有意义了。
票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/41042

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档