0

I have the variable cards with empty values:

(def cards [0 0 0])

Im trying to set a value of cards (depending on input) to a 3 within a function. Thats why i have the following code:

(defn parse-int [s]
  (Integer. (re-find  #"\d+" s )))

(defn changevalue [] (assoc cards (parse-int (read-line)) 3)) 
(changevalue) 

But when i execute the problem and typ in my input 1, the function doesn't change the value of key 1, and when i print it, its still 0 0 0 . How do I fix this?

Im sure the parse-int works, i got it from: In Clojure how can I convert a String to a number?

Jelle
  • 758
  • 2
  • 14
  • 36

2 Answers2

4

Firstly, just use Integer/parseInt to parse the input:

(defn change-value [cards]
  (let [s (read-line)]
    (assoc cards (Integer/parseInt s) 3)))

This function returns a copy of cards, with one of its elements changed. Remember, cards is a vector, which is immutable. You can't change it once it's been created.

You wrote "the function doesn't change the value of key 1, and when i print it, its still 0 0 0 . How do I fix this?" You don't fix it, you embrace immutability. Don't try to change cards. Use the modified copy that change-value returns:

(def cards [0 0 0])
(def changed-cards (change-value cards))

(println cards)
(println changed-cards)

If you really, really, really need mutability, you can use an atom, but that shouldn't be your first option. Clojure is a functional language with heavy emphasis on immutability. Go with the flow instead of trying to fight the language.

Carcigenicate
  • 43,494
  • 9
  • 68
  • 117
1

Clojure's data structure is almost immutable. In clojure, substitution for mutating values is restricted strictly. If you want mutable data structure, you can use Java's mutable data structure or clojure's {atom,ref,var}.

If you truly want to mutate cards, try do this:

(def cards (atom [0 0 0]))
(defn change-cards! [idx] (swap! cards assoc idx 3))
(change-cards! 2)
@cards
#_"here is no parseint to simplify your problem"
naoki fujita
  • 689
  • 1
  • 9
  • 13