Clojure : define 2D-primitives arrays like double[][] [duplicate] - arrays

This question already has answers here:
How do I create a primitive two-dimensional (2d) array of doubles in Clojure?
(2 answers)
Closed 6 years ago.
I have a 2D vector like
(def data [[1 1] [1 1]])
I would like to turn it into double[][].
i examined clojure.core and I tried :
1)
(->> (map double-array data)
(to-array-2d))
Unfortnately it returns Object[][] type of data, which fails in Java interop.
2)
(->> (map double-array data)
(double-array))
Of course it does not work because double-array expects a collection of numbers
3) I did not code it since it's heavy and I do not know if something esle exist but I could initialize a double[][] with (make-array Double/Type 2 2) [2 2 got by alen] and then fill it with loops.
Like in Java in fact.
4) A short way but a bit twisted
(def double-2d-array-type
(type (double-array [])))
(->> (map double-array data)
(into-array double-2d-array-type)))
Is there a direct way ? If it was possible to call directly double[] it would be better.
Like "(into-array double[] data)"

Just remove the first argument to into-array:
(into-array (map double-array data))
As long as there is at least one element in the input sequence, into-array can look at its type to guess the desired type of the output array. This guess isn't always what you want, because of inheritance, but for primitives it will never be wrong.

Related

Multiplying an array by a number

I've been writing out a function in Clojure that would take a row of a 2d array and then multiples the values in it by a single value. I have the index to get the specific row and the value to multiply the row with in another array.
The function will return the array, that has now got values multipled by the single value.
Here's the code:
(def twod-array [[3.1 0.0023 0.35]
[0.21 0.00353 8.13]])
(def iandv [1 3.1])
(defn array-multiply [iandv twod-array]
(
let [array-row (nth twod-array (nth iandv 0))]
(map * [array-row] [(nth iandv 1)])
)
The let gets the array row and then it will return the row with the values inside multiplied with the value of the "index and value" array.
This has the closest I've gotten using the examples with the clojure.doc website and I'm getting a ClassCastException of the following:
ClassCastException clojure.lang.PersistentVector cannot be cast to java.lang.Number clojure.lang.Numbers.multiply (Numbers.java:148)
I've been looking at map vector and other map functions but I haven't been able to find a good solution.
more clojurish way could look something like this:
(defn array-multiply [[row mul] twod-array]
(update twod-array row #(mapv (partial * mul) %)))
user> (array-multiply iandv twod-array)
;;=> [[3.1 0.0023 0.35] [0.651 0.010943000000000001 25.203000000000003]]
Your code is somewhat hard to read, but basically, you're trying to multiply a number and a vector, that doesn't work.
(defn array-multiply [iandv twod-array]
(let [array-row (nth twod-array (nth iandv 0))]
(map * array-row [(nth iandv 1)])))
works since array-row already is a vector.

how apply function on all element of array and get result as array in clojure?

generally i want to know when we have array of object that have some property can same the "Object Literal in JavaScript" can calculated with specific function. i want to create that property for my array in clojure to apply some calculation on them such as sorting or more simpler finding maximum according to that property.for example how try find maximum in this example?
(def aSqh (fn [x] (* x x)))
(def maSqh (max (apply aSqh [1 2 3 4])))
the have error that output is object and not number
You seem to be thinking of a mapping operation (take a function of one argument and a collection, replace every element with the result of the function on that element), which in Clojure is called map. apply is a function for plumbing collections into functions as if they were given each element as a separate argument. Usually you want to use it with variadic functions (i.e. functions such as max, that take a variable number of arguments). For instance
(def maSqh (apply max (map aSqh [1 2 3 4]))) ;;=> 16
If you want to preserve the datatype of a collection after performing a mapping, you can use into and empty:
(defn preserving-map [f coll]
(into (empty coll) (map f coll)))
(preserving-map aSqh [1 2 3 4]) ;;=>[1 4 9 16]
(preserving-map aSqh #{1 2 3 4}) ;;=> #{1 4 9 16}
but this removes the (useful) laziness that map usually gives us. For the particular case of vectors (like [1 2 3 4]), this use case is common enough that there is mapv which eagerly performs mappings and puts them into a vector.

Last element of an Array in Clojure

Is there any simplier way to find the last element of an array in clojure except this function?
(fn [l] (if (empty? (rest l)) (first l) (recur (rest l))))
For vectors, use peek for constant time
user=> (peek [1 2 3 4 5])
5
For Java arrays,
user=> (let [a (to-array [1 2 3 4 5])] (aget a (dec (alength a))))
5
For a general collection, you can get the last item in linear time with last. It is defined similarly to what you have done.
user=> (source last)
(def
^{:arglists '([coll])
:doc "Return the last item in coll, in linear time"
:added "1.0"
:static true}
last (fn ^:static last [s]
(if (next s)
(recur (next s))
(first s))))
The simplest way is to use (last l) that works in linear time (http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/last)
Another possibility is to reverse your collection and take the first element: ((comp first reverse) l). But that's rather slow as reverse returns a non-lazy sequence. Note: comp returns a composition of its arguments (functions) (http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/comp)
You can also convert the collection to a vector first and then apply peek: ((comp peek vec) l). This should have a better performance.
Another one: determine the length of your collection and take the last element (#(nth % (dec (count %))) l).
These functions work for all collection types (e.g. vectors, lists, ...). There are no arrays per se in Clojure (except you want to use Java arrays).

How to store a broken-Scheme-string in an array or a vector?

I get as an input a string , and I want to store it in an array or
a vector , so I would be able to check the values of the broken string .
Here I break the string into chars :
(define (dealBreaker str) (string->list str)) ; break the string into chars
But when I try to declare a simple vector :
(define (myVector (make-vector 4 (/ 1 2))))
I get this : #%plain-lambda: not an identifier in: (make-vector 4 (/ 1 2))
How can I declare a vector called someVector for the broken characters from dealBreaker method above ?
Try this, for some str string:
(define (dealBreaker str)
(list->vector (string->list str)))
(define myVector (dealBreaker "some string"))
myVector
=> '#(#\s #\o #\m #\e #\space #\s #\t #\r #\i #\n #\g)
The above will create a new vector from the characters in the string, is that what you need?
The problem here is that define should be
(define identifier value)
but right now you have
(define (identifier value))
So try
(define myVector (make-vector 4 (/ 1 2)))
It's a little confusing, because in Scheme, define is overloaded, there's also
(define (functionName formals) body)
but that's purely syntactical sugar for
(define functionName
(lambda formals body))
Side note: Several beginner scheme textbooks recommend using the lambda version since it's more explicit.
In this case though, just do:
(define myVec (list->vector (dealBreaker str)))
The immediate problem you're having with myVector appears to be due to a misplaced paren - try this instead and see if it resolves the 'plain-lambda' error:
(define myVector (make-vector 4 (/ 1 2)))
On the question of converting the 'dealBreaker' string to a vector, you should be able to do this:
(define (someVector dealBreakerList) (list->vector dealBreakerList))
(someVector (dealBreaker "someString"))
Or if you want 'someVector' as the complete function:
(define (someVector str) (list->vector (string->list str)))
(someVector "someString")

Parsing of nested array structure

I'm trying to parse a nested array structure of the following form:
[element [[child1] [child2] [child3 [[subchild1] [subchild2]]]]]
I would also like to return a list with all symbols (and nothing else), regardless of nesting depth; however, I'm not looking for flatmap or flatten etc, since I need to perform more complicated additional work on every element.
This is what I came up with so far:
(defn create-element [rs element]
(if (symbol? element)
(cons element rs)
rs))
(defn parse
([rs element] (create-element rs element))
([rs element [children & more]] (if (nil? more)
(parse (parse rs element) (first children))
(parse (parse rs element) (first children) more))))
(defn n-parse [element]
(apply parse () element))
This works fine for the following input:
=> (n-parse ['bla [['asd] ['kkk] ['sss]]])
(sss kkk asd bla)
But this doesn't work:
=> (n-parse ['bla [['asd] ['kkk [['ooo]]] ['sss]]])
(sss kkk asd bla)
I'm still trying to wrap around my head around the types but can't seem to manage to get it right. For example, Haskell makes this easy with pattern matching etc, whereas Clojure doesn't allow same arity function overloading.
Also is there a more concise / idiomatic way (without having to resort to if?) I'd prefer pure Clojure solutions (no external libs) since this is actually for a Clojurescipt project.
Many thanks for any help!
I don't see whats wrong with flatten. If you want to do some work on the items first, do the work first and then flatten the result:
(defn map-tree
"Example: (map-tree + [1 2 [3 5]] [3 4 [5 6]])"
[f & trees]
(if (every? coll? trees)
(apply map (partial map-tree f) trees)
(apply f trees)))
(defmulti transformator identity)
;; transform 'sss element into something special
(defmethod transformator 'sss [_] "sss")
;; default transformation
(defmethod transformator :default [v] v)
Test:
user> (flatten (map-tree transformator '[bla [[asd] [kkk] [sss]]]))
(bla asd kkk "sss")
user>
Would that not work?

Resources