Clojure新手求助:如何修改矩阵(向量的向量)的指定元素
Hey there! Since you're new to Clojure and functional programming, let's break this down step by step to solve your problem of replacing the second element in each sub-vector of your matrix with a corresponding string.
First, let's recap your input matrix:
(def s [[1 1 1 3] [2 2 2 3] [3 2 1 1] [4 3 3 4]])
Step 1: Define Your Value-to-String Mapping
First, set up a map to define which string each numeric value should map to. Let's use your example hints (1 → "Joe", 2 → "Fred") plus a default for 3 (like "Bob"):
(def value-to-name {1 "Joe", 2 "Fred", 3 "Bob"})
You can easily add more key-value pairs here later if you need to handle other numbers.
Step 2: Transform the Matrix
Clojure prioritizes immutable data, so we'll create a new matrix instead of modifying the original one. We'll use mapv (which returns a vector, matching your original structure) to process each sub-vector, and assoc to replace the second element (remember, Clojure uses 0-based indexing—so the second element lives at index 1):
(def new-s (mapv #(assoc % 1 (get value-to-name (% 1))) s))
Let's break down that line for clarity:
mapv: Iterates over every sub-vector insand returns a new vector of transformed sub-vectors (keeping your matrix structure intact).#(...): A concise anonymous function that takes each sub-vector as the parameter%.assoc % 1 ...: Replaces the element at index 1 of the sub-vector%with the value we retrieve next.(get value-to-name (% 1)): Grabs the second element of the sub-vector ((% 1)), then looks up its corresponding string in our mapping. If a number doesn't have a matching entry,getreturnsnilby default—you can add a fallback like(get value-to-name (% 1) "Unknown")to handle unexpected values gracefully.
Step 3: Check the Result
If you run (println new-s), you'll get exactly the output you're expecting:
[[1 "Joe" 1 3] [2 "Fred" 2 3] [3 "Fred" 1 1] [4 "Bob" 3 4]]
Extra Tip for Simple Conditions
If your mapping is short and you don't want to define a separate map, you can use condp for inline condition checks instead:
(def new-s (mapv #(assoc % 1 (condp = (% 1) 1 "Joe" 2 "Fred" 3 "Bob" "Unknown")) s))
This works great for small sets of values and keeps the logic explicit right in the transformation code.
内容的提问来源于stack exchange,提问作者NuclearFish

