2012-01-07 5 views
2

맵 조작에서 리턴 된 (게으른) 시퀀스를 다른 맵 조작으로 전달하려고하므로 요소를 찾을 수 있습니다 첫 번째 순서대로. 이 코드는 텍스트/행 형식의 텍스트 파일에서 일부 축구 비품을 파싱하고 정리 한 다음지도를 반환합니다. 여기 Clojure 예외를 방지하는 방법 : clojure.lang.LazySeq를 clojure.lang.IFn으로 캐스팅 할 수 없습니다.

코드입니다 :

(ns fixtures.test.lazytest 
    (:require [clojure.string :as str]) 
    (:use [clojure.test])) 

(defn- column-map 
    "Produce map with column labels given raw data, return nil if not enough columns" 
    [cols] 
    (let [trimmed-cols (map str/trim cols) 
     column-names {0 :fixture-type, 1 :division, 2 :home-team, 4 :away-team}] 
    (if (> (count cols) (apply max (keys column-names))) 
     (zipmap (vals column-names) (map trimmed-cols (keys column-names))) 
     nil))) 

(deftest test-mapping 
    (let [cols '["L" " Premier " " Chelsea " "v" "\tArsenal "] 
     fixture (column-map cols)] 
    (is (= "Arsenal" (fixture :away-team))) 
    (is (= "Chelsea" (fixture :home-team))) 
    (is (= "Premier" (fixture :division))) 
    (is (= "L" (fixture :fixture-type))) 
) 
) 

(run-tests 'fixtures.test.lazytest) 

내가 데려 갈거야 접근 방식은 다음과 같습니다

  1. 정리
  2. 이 zipmap 사용하여 열 데이터의 벡터 (선행/후행 공백을 제거) 열 이름 키워드를 열 데이터의 해당 요소와 결합하십시오 (모든 열이 사용되는 것은 아님).
clojure.lang.LazySeq 내가 생각

clojure.lang.IFn

캐스트 할 수없는 10

문제는

java.lang.ClassCastException가 발생 zipmap에 손질-COLS를 사용한다 나는 이것이 일어나고있는 이유를 알고 있습니다 ... trimmed-cols은 LazySeq입니다. zipmap에서 호출 된지도는 첫 번째 인수로 비 함수를받는 것을 반대합니다.

내가 하게 변경할 수 있습니다이 문제를 해결하려면 다음

trimmed-cols (vec (map str/trim cols)) 

을하지만이 "최고"옵션처럼 생각하지 않습니다.

그래서 :

  1. 다른 맵에 "기능"인수로 맵 작업의 결과를 사용하기위한 좋은 일반적인 솔루션이 있습니까?
  2. 원시 값 데이터의 벡터에서 {: 값} 쌍의 맵을 유도하는 더 나은 방법이 있습니까? 모든 벡터 요소가 사용되는 것은 아닙니다.

(나는 관용적 솔루션을을 요구하지만, 상상 주저 어딘가에 반드시이 일의 일반적으로 인정 된 방법을합니다.)

답변

3

당신이 계신 완전히 확실하지 않다,하지만 난 귀하의 코드가 실패한 이유를 확인할 수 있습니다 - 말했듯이 trimmed-cols은 기능이 아닙니다. 이것은 단순히 작동하지 않을까요?

저는 건너 뛸 항목에 :_dummy 키를 사용하고 있습니다. column-names 벡터에서 원하는만큼 많이 사용할 수 있습니다 : zipmap은이를 하나로 합칩니다.이 코드는 dissoc으로 제거됩니다. 니스

(defn- column-map 
    "Produce map with column labels given raw data, return nil if not enough columns" 
    [cols] 
    (let [trimmed-cols (map str/trim cols) 
     column-names [:fixture-type :division :home-team :_dummy :away-team]] 
    (if (>= (count cols) (count column-names)) 
     (dissoc (zipmap column-names trimmed-cols) :_dummy) 
     nil))) 

(column-map ["L" " Premier " " Chelsea " "v" "\tArsenal "]) 
; => {:away-team "Arsenal", :home-team "Chelsea", :division "Premier", :fixture-type "L"} 
+0

... 난 당신의 솔루션은 zipmap 호출을 단순화하는 방법, 그리고 키워드 이름은 무슨 일이 일어나고 있는지 분명히 (어)하게, 그래서 이것은 내 질문의 두 번째 부분을 해결합니다. 첫 번째 부분에서지도 결과를 (vec ...)를 사용하여 벡터로 변환하면 함수로 액세스 할 수 있습니다 (작은 목록 크기에서는 괜찮을 것입니다). –

관련 문제