Fork me on GitHub
#clojure-italy
<
2017-09-22
>
reborg13:09:46

buon venerdi'

reborg15:09:19

Cosa usereste voi per risolvere il seguente?

(def input
[["FooYep"]
 ["BlahBlah:" "FooFoo"]
 ["BazBaz" "PatPat"]
 ["TypeA"]
 ["Foo1" "East" "North" "South"]
 ["10.0" "11.0" "12.0" "13.0"]
 ["A1" "MDD"]
 ["ClassA" "34.97" "33.6" "34.5"]
 ["ClassB" "11.7" "11.4"]
 ["Foo" "MDD"]
 ["TypeA"]
 ["Foo1" "East" "North" "South"]
 ["10.0" "11.0" "12.0" "13.0"]
 ["A1" "MDD"]
 ["ClassA" "34.97" "33.6" "34.5"]
 ["ClassB" "11.7" "11.4"]
 ["ClassC" "11.7" "11.4"]])

reborg15:09:27

Filtrare gruppi di vectors che matchano le seguenti regole: * 1 Vector di due elementi * Seguito da 1 o + vector che iniziano con str e poi nums

reborg15:09:34

Expected:

[[["A1" "MDD"]
  ["ClassA" "34.97" "33.6" "34.5"]
  ["ClassB" "11.7" "11.4"]]
 [["A1" "MDD"]
  ["ClassA" "34.97" "33.6" "34.5"]
  ["ClassB" "11.7" "11.4"]
  ["ClassC" "11.7" "11.4"]]]

richiardiandrea15:09:50

@reborg mi sembra un buon use case per clojure.spec

richiardiandrea15:09:15

Almeno per quanto riguarda il "pattern" matching

reborg16:09:10

first cut

(let [v input]
  (loop [res [] idx 0]
    (if (= idx (count v))
      res
      (let [current (v idx)]
        (if (= 2 (count current))
          (let [more
                (conj res
                      (loop [idx2 (inc idx) res [(v idx)]]
                        (if (and (string? (first (v idx2)))
                                 (> (count (v idx2)) 2)
                                 (re-find #"\d+" (or (second (v idx2)) "")))
                          (recur (inc idx2) (conj res (v idx2)))
                          res)))]
            (if (> (count (first more)) 1)
              (recur more (inc idx))
              (recur res (inc idx))))
          (recur res (inc idx)))))))

reborg16:09:47

e' un pattern matching con look ahead. Primo loop vado sugli indici. Se trovo match iniziale, parto col secondo loop

reborg16:09:18

ci dev'essere qualche lib che lo fa senno' metto a posto questo

bronsa16:09:42

@reborg mi sembra un ottimo use case per spec

bronsa16:09:06

qualcosa come

(s/def ::group-start (s/coll-of any? :kind vector? :count 2))
(s/def ::group-body-item (s/cat :start string? :rest (s/+ (every-pred #(re-matches #"\d+(\.\d+)?" %) string?))))
(s/def ::group-body (s/+ (s/spec ::group-body-item)))
(s/def ::group (s/cat :start ::group-start :body ::group-body))
per descrivere un singolo gruppo

bronsa16:09:11

e poi iteri conformando

reborg17:09:18

ok... non sapevo che spec mi potesse aiutare qui 🙂

reborg17:09:26

mo lo provo

bronsa17:09:37

beh, è un problema di parsing e spec è un parser engine

reborg18:09:23

non so come iterare conformando... capisco che posso trovare un pattern con ::group, ma sembra che lo debba isolare prima... ma non so quanto e' lungo. Oppure non ho capito