Take a function which inputs a set, set of sets, collection, nested vector with collections buried within, etc. So, the inputs sometimes are not of the same type. How would one go about converting such input into a nested vector structure? In the first case of just a set, I would use
(into [] #{1 2 3 4})
converting the into into a vector.
But the case of sets within sets, I am unable to output nested vectors, i.e.
#{1 2 3 #{1 2 3}}
Similarly, I might have an input such as
[1 2 3 (4 5 6)]
and I want to output
[1 2 3 [4 5 6]]
The idea is that sometimes I need to go within the depth and pick out a collection or set to turn into a vector. Is it possible to have a function, which in general can handle the many different structural inputs and output a nested vector structure. Namely can a function generalize the aforementioned examples? I simplified the samples somewhat, for instance I might have inputs such as
[[[1 2 3 4] [#{1 2 3 4} 2 3 4] [(1 2 3 4) 2 3 4]]]
To give more insight into the function I am trying to work on consider the function C from the language R. The importance of this function lies in the importance of vector structures within statistics/data analysis.
user=> (use 'clojure.walk)
user=> (clojure.walk/postwalk (fn [e] (if (coll? e) (vec e) e)) '(1 2 3 #{4 5 6 (7 8 9)}))
[1 2 3 [4 5 6 [7 8 9]]]
a naive reduce implementation:
(defn to-vectors [c]
(reduce #(conj %1 (if (coll? %2) (to-vectors %2) %2))
[] c))
user=> (to-vectors '[[[1 2 3 4] [#{1 2 3 4} 2 3 4] [(1 2 3 4) 2 3 4]]])
[[[1 2 3 4] [[1 2 3 4] 2 3 4] [[1 2 3 4] 2 3 4]]]
Related
Given the array:
arr = [1 2; 3 4; 5 6]
3×2 Array{Int64,2}:
1 2
3 4
5 6
which is flattened flat_arr = collect(Iterators.flatten(arr))
6-element Array{Int64,1}:
1
3
5
2
4
6
I sometimes need to go between both index formats. For example, if I got the sorted indices of flat_arr, I may want to iterate over arr using these sorted indices. In Python, this is typically done with np.unravel_index. How is this done in Julia? Do I just need to write my own function?
vec() creates a 1-d view of the array. Hence you can have both pointers to the array in the memory and use whichever one you need in any minute (they point to the same array):
julia> arr = [1 2; 3 4; 5 6]
3×2 Array{Int64,2}:
1 2
3 4
5 6
julia> arr1d = vec(arr)
6-element Array{Int64,1}:
1
3
5
2
4
6
julia> arr1d[4] = 99
99
julia> arr
3×2 Array{Int64,2}:
1 99
3 4
5 6
Note that in Julia arrays are stored in column major order and hence the fourth value is the first value in the second column
This can be accomplished using CartesianIndices.
c_i = CartesianIndices(arr)
flat_arr[2] == arr[c_i[2]]) == 3
I would like sum a vector containing a mixture of doubles and vectors. Something like,
[[1 2 1 [1 2 3]] [1 2 4 [1 1 1]]...]
That I would like to sum such that I get something like,
[212 12 444 [11 2 12]]
Is there an efficient way to do this using core clojure functions like reduce or map?
I think that you want to have a function that adds a nested vector structure, so that (nvadd [1 2 1 [1 2 3]] [1 2 4 [1 1 1]]) evaluates to [2 4 5 [2 3 4]]. You can then reduce your vector of such vectors with that function.
(defn nvadd [a b]
(mapv #(if (vector? %1)
(nvadd %1 %2)
(+ %1 %2))
a b))
This assumes well-formed input.
If I want to create 2D array with 1 row by 5 columns.
I could do this
julia> a = [1 2 3 4 5]
1×5 Array{Int64,2}:
1 2 3 4 5
But to create 2D array with 5 rows by 1 column. I have tried
julia> b = [1; 2; 3; 4; 5]
5-element Array{Int64,1}:
1
2
3
4
5
But I got back a 1D array which is NOT what I wanted
The only way to get it to work is
julia> b=reshape([1 2 3 4 5],5,1)
5×1 Array{Int64,2}:
1
2
3
4
5
Perhaps I am missing some crucial information here.
You could also do a = [1 2 3 4 5]'.
On a side note, for Julia versions > 0.6 the type of a wouldn't be Array{Int64, 2} but a LinearAlgebra.Adjoint{Int64,Array{Int64,2}} as conjugate transpose is lazy in this case. One can get <= 0.6 behavior by a = copy([1 2 3 4 5]').
AFAIK there is no syntactic sugar for it.
I usually write:
hcat([1, 2, 3, 4, 5])
which is short and I find it easy to remember.
If you use reshape you can replace one dimension with : which means you do not have to count (it is useful e.g. when you get an input vector as a variable):
reshape([1 2 3 4 5], :, 1)
Finally you could use:
permutedims([1 2 3 4 5])
When I'm comparing, for example, the following line (These numbers are sample data and can vary).
(map < '[1 2 3 4 5 6] [4 2 3 4 5 9])
I want be able to check if the output contains a false boolean. If it does I want to do some logic, otherwise I want to do some different logic.
This is what I have so far:
(if(map < '[1 2 3 4 5 6] [4 2 3 4 5 9])
// True logic
// False logic)
Thus far it always goes to the true line and never the false line with what ever data I insert. Is there a way I can acheive this?
You could use some with the predicate false?:
(some false? (map < '[1 2 3 4 5 6] [4 2 3 4 5 9])) ;;=> true
(if (some false? (map < '[1 2 3 4 5 6] [4 2 3 4 5 9]))
'True
'False) ;;=> True
http://www.4clojure.com/problem/23: "Write a function which reverses a sequence"
One solution is (fn [x] (reduce conj () x)), which passes all the tests. However, I'm curious why that solution works for the first test:
(= (__ [1 2 3 4 5]) [5 4 3 2 1])
Inlining the function evaluates to true in the REPL:
(= ((fn [x] (reduce conj () x)) [1 2 3 4 5]) [5 4 3 2 1])
true
However, if I evaluate the first argument to the =, I get (5 4 3 2 1), and (= (5 4 3 2 1) [5 4 3 2 1]) throws a ClassCastException.
Why does the former work while the latter doesn't? It seems like they should be equivalent …
The problem is that your list literal (5 4 3 2 1) is being evaluated as a function call. To use it properly you need to quote it, like so:
(= '(5 4 3 2 1) [5 4 3 2 1]) ;; => true
another way to do it without reduce is to use into ()
as it works exatcly as your reduction. So when you fill the blank this way, it solves the task:
(= (into () [1 2 3 4 5]) [5 4 3 2 1]) ;; true
(= (into () (sorted-set 5 7 2 7)) '(7 5 2)) ;; true
(= (into () [[1 2][3 4][5 6]]) [[5 6][3 4][1 2]]) ;; true