li berrouz
li berrouz

Reputation: 43

How I can get element from set in clojure?

I have set

(def tableOfStates [{:_ '\a :q0 'q1 :q1 'q1 :q2 'q3 :q3 '\_ }
                    {:_ '\b :q0 'q2 :q1 'q3 :q2 'q2 :q3 '\_}
                    {:_ '\c :q0 'q3 :q1 'q3 :q2 '\_ :q3 '\_}
                    {:_ '\$ :q0 '\_ :q1 '\_ :q2 '\_ :q3 'pass}])

And I want get element this way

((get tableOfStates 0) ":q0")

But returns nil

How can I make this?

Upvotes: 2

Views: 1954

Answers (2)

Thumbnail
Thumbnail

Reputation: 13483

You can do this more neatly - and faster - if you change the tableOfStates, a state transition table, from a vector of maps to a map of maps:

(def tableOfStates {'\a {:q0 'q1 :q1 'q1 :q2 'q3 :q3 '\_}
                    '\b {:q0 'q2 :q1 'q3 :q2 'q2 :q3 '\_}
                    '\c {:q0 'q3 :q1 'q3 :q2 '\_ :q3 '\_}
                    '\$ {:q0 '\_ :q1 '\_ :q2 '\_ :q3 'pass}})

We use it like this:

((get tableOfStates \a) :q0) ;q1

... or just

((tableOfStates \a) :q0) ;q1

... since a map works as its own get function.

We use \a directly. We don't have to look for it with the :_ key.

I think you are under the impression that keys have to be keywords, and vice versa. Not so! As things are, the states are represented differently depending on what role they play:

  • As keys, they are keywords :q0, :q1, :q2, and :q3.
  • As values, they are the corresponding symbols 'q0, 'q1 'q2, and 'q3.
  • The (I assume) failed state is represented by the character \_. (There is no need to quote characters, by the way).

Let's represent them all as keywords. The table becomes ...

(def tableOfStates {\a {:q0 :q1, :q1 :q1, :q2, :q3, :q3 :_}
                    \b {:q0 :q2, :q1 :q3, :q2 :q2, :q3 :_}
                    \c {:q0 :q3, :q1 :q3, :q2 :_, :q3 :_}
                    \$ {:q0 :_, :q1 :_, :q2 :_, :q3 :pass}})

Other changes.

Use nil instead of :_ to represent the fail state. Then you don't need the failing transitions:

(def tableOfStates {\a {:q0 :q1, :q1 :q1, :q2 :q3}
                    \b {:q0 :q2, :q1 :q3, :q2 :q2}
                    \c {:q0 :q3, :q1 :q3}
                    \$ {:q3 :pass}})

For example,

((tableOfStates \$) :q0) ;nil

It looks as though \$ represents end of input. If this is supplied, good and well. If not, you might do better to test the final state with the set #{:q3}.

Upvotes: 1

johnbakers
johnbakers

Reputation: 24771

(get-in tableOfStates [0 :q0])

This returns the value you are looking for, which is the value associated with the key :q0 of the first element in the vector.

If you must work with a string, do this:

(get-in tableOfStates [0 (keyword "q0")])

This converts the string to a keyword first.

From the REPL:

> tableOfStates
[{:_ \a, :q0 q1, :q1 q1, :q2 q3, :q3 \_}
 {:_ \b, :q0 q2, :q1 q3, :q2 q2, :q3 \_}
 {:_ \c, :q0 q3, :q1 q3, :q2 \_, :q3 \_}
 {:_ \$, :q0 \_, :q1 \_, :q2 \_, :q3 pass}]
> (get-in tableOfStates [0 :q0])
q1
> (keyword "str")
:str
> (get-in tableOfStates [0 (keyword "q0")])
q1
> 

Upvotes: 2

Related Questions