Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Given the following code, I have written a for loop that returns a key and value (0 or 1) of file names passed. 1 means present, and 0 means not present.

Is there a way to construct a flat map without having to use into?

(defn kind-stat
  [filename expected-type]
  (let [f (File. filename)
        s (cond
              (.isFile f)      "f"
              (.isDirectory f) "d"
              (.exists f)      "o" 
              :else            "n" )]

      (if (= expected-type s)
        0
        1)))

(defn look-for 
  [filename expected-type]
    (let [find-status (kind-stat filename expected-type)]
      find-status))

(defn all-files-present?
"Takes a list of real file names, and returns a sequence of maps 
 indicating the file name and its availability status 1 for present 
 and 0 for not present. Please note look-for returns 0 for success, 
 so its return logic needs to be reversed for the return sequence 
 of maps."
  [file-seq]
  (for [fnam file-seq
    :let [stat-map {(keyword fnam) 
       (if (= (look-for fnam "f") 0)
           1
           0)}]]
   stat-map))

(into {}  
 (all-files-present? '("Makefile" "build.sh" "real-estate.csv")))

{:Makefile 1, :build.sh 1, :real-estate.csv 0}
share|improve this question
    
I agree, this belongs on codereview. Though I would get rid of your let and if, and make them one whole, and have expected type be the function that accepts f so instead of f, d, o, h, you actually hand it .isFile .isDirectory .exists. That's the critique I would give on code review in my immediate albeit small review. Also I would return instead of 1 or 0 in the sequence, make it the closure to execute to find out if it's present, since it's presence may be transient and can then be checked as needed. –  Jimmy Hoffa Dec 27 '12 at 17:28
    
What is the purpose of this code? Do you want to know if all files are present, or if each file is present? If it's an all or nothing, you just need to do a reduce with the kind-stat returning true/false and an and –  Jimmy Hoffa Dec 27 '12 at 17:55
add comment

migrated from programmers.stackexchange.com Dec 27 '12 at 17:48

This question came from our site for professional programmers interested in conceptual questions about software development.

1 Answer

up vote 2 down vote accepted

You could use zipmap:

(defn all-files-present?
  [file-seq]
  (let [f  #(bit-flip (look-for % "f") 0)]
    (zipmap (map keyword file-seq) (map f file-seq))))

or juxt:

(defn all-files-present?
  [file-seq]
  (let [f  #(bit-flip (look-for % "f") 0)]
    (into {} (map (juxt keyword f) file-seq))))

Note that I use bit-flip instead of the if to flip 1<->0.


It would be nicer if kind-stat would just return a boolen value, so you would simply use

(defn kind-stat
  [filename expected-type]
  (let [f (File. filename)]
      (= expected-type 
        (cond
          (.isFile f)       "f"
          (.isDirectory f)  "d"
          (.exists f)       "o" 
           :else            "n"))))

(defn all-files-present?
  [file-seq]
  (let [f  #(if (kind-stat % "f") 1 0)]
    (into {} (map (juxt keyword f) file-seq))))

I removed look-for, since it is virtually useless.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.