2

I am working on a problem to read in a file with lines like:

A abcdefg
B bcdefgh

But I keep getting errors about Lazy Sequence not compatible with Java Charseq ..

I tried:

(def notlazy (doall lyne2))

Then thought I verified:

(realized? notlazy)
true

But still:

(str/split notlazy #" ")
ClassCastException class clojure.lang.LazySeq cannot be cast to class
  java.lang.CharSequence (clojure.lang.LazySeq is in unnamed module of
  loader 'app'; java.lang.CharSequence is in module java.base of loader
  'bootstrap')  clojure.string/split (string.clj:219)

Help please!

0

2 Answers 2

6

The first argument to str/split must be a CharSequence to be split. Presumably you want to split each input line in the sequence for which you can use map without needing to eagerly evaluate the input sequence:

(map (fn [line] (str/split line #" ")) lyne2)
Sign up to request clarification or add additional context in comments.

Comments

1

Expanding on the previous result a bit, we have this example. You can reproduce the following using this template project.

(ns tst.demo.core
  (:use demo.core tupelo.core tupelo.test)
  (:require
    [clojure.java.io :as io]
    [tupelo.string :as str]
    ))

(def data-file
  "A abcdefg
   B    bcdefgh
  ")

(dotest
  ; Version #1
  (let [lines      (line-seq (io/reader (str/string->stream data-file)))
        lines2     (remove str/blank? lines)
        lines3     (map str/trim lines2)
        line-words (mapv #(str/split % #"\s+") lines3) ; "\s+" => "one or more whitespace chars"
        ]
    (spyxx lines)
    (spyxx lines2)
    (spyxx lines3)
    (spyxx line-words))

with result:

--------------------------------------
   Clojure 1.10.2-alpha1    Java 15
--------------------------------------

Testing tst.demo.core
lines       => <#clojure.lang.Cons ("A abcdefg" "   B    bcdefgh" "  ")>
lines2      => <#clojure.lang.LazySeq ("A abcdefg" "   B    bcdefgh")>
lines3      => <#clojure.lang.LazySeq ("A abcdefg" "B    bcdefgh")>
line-words  => <#clojure.lang.PersistentVector [["A" "abcdefg"] ["B" "bcdefgh"]]>

This shows the type of each result along with its value. We use string->stream so we don't need to set up a dummy file to read from.

The following shows how it would typically be written in real code (not as a demo exercise like Version #1). We use the "thread-last" operator, and write a unit test to verify the result:

  ; Version #2
  (let [result (->> data-file
                 (str/string->stream)
                 (io/reader)
                 (line-seq)
                 (remove str/blank?)
                 (map str/trim)
                 (mapv #(str/split % #"\s+"))) ; "\s+" => "one or more whitespace chars"
        ]
    (is= result [["A" "abcdefg"] ["B" "bcdefgh"]])))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.