This page is not created by, affiliated with, or supported by Slack Technologies, Inc.

## 2022-08-25

## Channels

- # announcements (4)
- # asami (26)
- # babashka (82)
- # beginners (27)
- # biff (6)
- # boot (1)
- # calva (42)
- # cider (2)
- # clj-commons (1)
- # clj-http-lite (2)
- # clj-kondo (37)
- # cljdoc (1)
- # clojure (46)
- # clojure-europe (34)
- # clojure-nl (1)
- # clojure-norway (7)
- # clojure-uk (2)
- # clojurescript (54)
- # code-reviews (18)
- # cursive (2)
- # datalevin (32)
- # datomic (7)
- # etaoin (1)
- # fulcro (9)
- # gratitude (3)
- # hyperfiddle (15)
- # introduce-yourself (1)
- # jobs (2)
- # lsp (32)
- # nrepl (1)
- # off-topic (18)
- # pathom (17)
- # pedestal (5)
- # polylith (89)
- # reitit (7)
- # releases (3)
- # remote-jobs (4)
- # shadow-cljs (52)
- # spacemacs (3)
- # squint (14)
- # tools-build (10)
- # tools-deps (18)
- # vim (4)
- # xtdb (34)

I wrote a function that takes a matrix and returns a vector of all the coefficients on the upper diagonals of the matrix, would love to get any feedback. Is there any way to avoid using flatten?

```
;; X_11 X_12 X_13
;; X = (X_21 X_22 X_23)
;; X_31 X_32 X_33
;; X = [X_11 X_22 X_33 X_12 X_23 X_13]
(defn vector-from-symmetric-matrix
"Given a symmetric matrix, represent it as a vector"
[X]
(let [size (count X)
row (flatten (map range (reverse (range (inc size)))))
col (flatten (map #(range % size) (range size)))]
(map (partial get-in X) (partition 2 (interleave row col)))))
```

if you're only flattening 1 level, you can use `mapcat`

:

```
user=> (flatten (map range (reverse (range 4))))
(0 1 2 0 1 0)
user=> (mapcat range (reverse (range 4)))
(0 1 2 0 1 0)
```

oh that's great thank you!

To support `mapcat`

, beware of `flatten`

: https://stuartsierra.com/2019/09/25/sequences-in-flatland

Also, your function will return a lazy seq (from `map`

), and not a vector as the name implies.

Thank you!

what is better, `apply vector`

or `into []`

`mapv`

if it's the final call

In cases like that, if `mapv`

won't do (like if your outer fn is `mapcat`

), wrap it in `vec`

.

Thanks, this is what I have now:

```
(defn vector-from-symmetric-matrix
"Given a symmetric matrix, represent it as a vector"
[X]
(let [size (count X)
row (mapcat range (reverse (range (inc size))))
col (mapcat #(range % size) (range size))]
(mapv (partial get-in X) (partition 2 (interleave row col)))))
```

Thanks!

suppose I wanted to assert that X was square, should I use `assert`

for that?

I haven't seen assert used much before

I just realized that "vector" is ambiguous in this context, so if "vector" in your fn name was meant in the mathematical sense (as it appears to be), returning a different kind of seq isn't necessarily "incorrect". Working with Clojure vectors tend to be simpler and more common, though.

You *can* use `assert`

, or add it as a `:pre`

-condition https://clojuredocs.org/clojure.core/defn

Or, for the Ultimate Power, you can do more thorough checks with https://clojure.org/guides/spec or https://github.com/metosin/malli

Now I have this:

```
(defn vector-from-symmetric-matrix
"Given a symmetric matrix, represent it as a vector"
[X]
{:pre [(apply = (map count X)) ;; Do the rows all have the same length?
(= (count X) (count (first X)))]} ;; does the number of rows match the number of columns?
(let [size (count X)
row (mapcat range (reverse (range (inc size))))
col (mapcat #(range % size) (range size))]
(mapv (partial get-in X) (partition 2 (interleave row col)))))
```