I am new to Rust and wanted to know whats the idomatic way to iterate over columns on a 2d vector.
I know how to do it for a rows, for example finding maximum for each row as below
let my_2d_vector: Vec<Vec<u64>> = vec![];
let max_in_each_rows = my_2d_vector.iter()
.map(|&row| row.iter().max())
.collect::<Vec<64>>();
How do I find maximum for each column without using loops?
One way to approach this functionally would be something like this:
let my_2d_vector: Vec<Vec<u64>> = vec![vec![1, 4, 3], vec![3, 3, 3]];
let max_in_each_col =
my_2d_vector
.iter()
.skip(1)
.fold(my_2d_vector[0].clone(), |mut maxes, row| {
maxes
.iter_mut()
.zip(row.iter())
.for_each(|(m, col)| *m = std::cmp::max(*m, *col));
maxes
});
println!("{:?}", max_in_each_col); // [3, 4, 3]
However, it's a misconception that loops aren't idiomatic Rust. You may find that the above isn't all that readable, and rustfmt formats it into 11 lines. Whereas using loops, although the logic is exactly the same, you get this
let my_2d_vector: Vec<Vec<u64>> = vec![vec![1, 4, 3], vec![3, 3, 3]];
let mut max_in_each_col = my_2d_vector[0].clone();
for row in &my_2d_vector[1..] {
for (m, col) in max_in_each_col.iter_mut().zip(row.iter()) {
*m = std::cmp::max(*m, *col);
}
}
println!("{:?}", max_in_each_col); // [3, 4, 3]
in only 6 lines and very readably.
In the following piece of Julia code, st.a and b are the same array, so when I delete an element from st.a, then this element is also deleted from b. Is it possible that a new array "*.a" is generated, every time a create an object * of Mystruct?
struct Mystruct
a::Array{Int64,1}
Mystruct(a::Array{Int64,1}) = new(a)
end
b = [1, 2, 3, 4]
st = Mystruct(b)
deleteat!(st.a,1)
I think that:
struct Mystruct
a::Array{Int64,1}
Mystruct(a::Array{Int64,1}) = new(copy(a))
end
will do the job you want.
I have an array with some values:
[1, 2, 3, 4]
I'd like to make a new array that contains mapped version of the items in the array above, but only add them to the new array if they pass a truth test.
A combination of map and filter?
[1, 2, 3, 4].mapFilter(function(n) { if (n > 2) return n * 3 })
What is this called?
This is map composed with filter. It doesn't need a name.
map (*3) . filter (>2)
I need to make a nested loop with an arbitrary depth. Recursive loops seem the right way, but I don't know how to use the loop variables in side the loop. For example, once I specify the depth to 3, it should work like
count = 1
for i=1, Nmax-2
for j=i+1, Nmax-1
for k=j+1,Nmax
function(i,j,k,0,0,0,0....) // a function having Nmax arguments
count += 1
end
end
end
I want to make a subroutine which takes the depth of the loops as an argument.
UPDATE:
I implemented the scheme proposed by Zoltan. I wrote it in python for simplicity.
count = 0;
def f(CurrentDepth, ArgSoFar, MaxDepth, Nmax):
global count;
if CurrentDepth > MaxDepth:
count += 1;
print count, ArgSoFar;
else:
if CurrentDepth == 1:
for i in range(1, Nmax + 2 - MaxDepth):
NewArgs = ArgSoFar;
NewArgs[1-1] = i;
f(2, NewArgs, MaxDepth, Nmax);
else:
for i in range(ArgSoFar[CurrentDepth-1-1] + 1, Nmax + CurrentDepth - MaxDepth +1):
NewArgs = ArgSoFar;
NewArgs[CurrentDepth-1] = i;
f(CurrentDepth + 1, NewArgs, MaxDepth, Nmax);
f(1,[0,0,0,0,0],3,5)
and the results are
1 [1, 2, 3, 0, 0]
2 [1, 2, 4, 0, 0]
3 [1, 2, 5, 0, 0]
4 [1, 3, 4, 0, 0]
5 [1, 3, 5, 0, 0]
6 [1, 4, 5, 0, 0]
7 [2, 3, 4, 0, 0]
8 [2, 3, 5, 0, 0]
9 [2, 4, 5, 0, 0]
10 [3, 4, 5, 0, 0]
There may be a better way to do this, but so far this one works fine. It seems easy to do this in fortran. Thank you so much for your help!!!
Here's one way you could do what you want. This is pseudo-code, I haven't written enough to compile and test it but you should get the picture.
Define a function, let's call it fun1 which takes inter alia an integer array argument, perhaps like this
<type> function fun1(indices, other_arguments)
integer, dimension(:), intent(in) :: indices
...
which you might call like this
fun1([4,5,6],...)
and the interpretation of this is that the function is to use a loop-nest 3 levels deep like this:
do ix = 1,4
do jx = 1,5
do kx = 1,6
...
Of course, you can't write a loop nest whose depth is determined at run-time (not in Fortran anyway) so you would flatten this into a single loop along the lines of
do ix = 1, product(indices)
If you need the values of the individual indices inside the loop you'll need to unflatten the linearised index. Note that all you are doing is writing the code to transform array indices from N-D into 1-D and vice versa; this is what the compiler does for you when you can specify the rank of an array at compile time. If the inner loops aren't to run over the whole range of the indices you'll have to do something more complicated, careful coding required but not difficult.
Depending on what you are actually trying to do this may or may not be either a good or even satisfactory approach. If you are trying to write a function to compute a value at each element in an array whose rank is not known when you write the function then the preceding suggestion is dead flat wrong, in this case you would want to write an elemental function. Update your question if you want further information.
you can define your function to have a List argument, which is initially empty
void f(int num,List argumentsSoFar){
// call f() for num+1..Nmax
for(i = num+1 ; i < Nmax ; i++){
List newArgs=argumentsSoFar.clone();
newArgs.add(i);
f(i,newArgs);
}
if (num+1==Nmax){
// do the work with your argument list...i think you wanted to arrive here ;)
}
}
caveat: the stack should be able to handle Nmax depth function calls
Yet another way to achieve what you desire is based on the answer by High Performance Mark, but can be made more general:
subroutine nestedLoop(indicesIn)
! Input indices, of arbitrary rank
integer,dimension(:),intent(in) :: indicesIn
! Internal indices, here set to length 5 for brevity, but set as many as you'd like
integer,dimension(5) :: indices = 0
integer :: i1,i2,i3,i4,i5
indices(1:size(indicesIn)) = indicesIn
do i1 = 0,indices(1)
do i2 = 0,indices(2)
do i3 = 0,indices(3)
do i4 = 0,indices(4)
do i5 = 0,indices(5)
! Do calculations here:
! myFunc(i1,i2,i3,i4,i5)
enddo
enddo
enddo
enddo
enddo
endsubroutine nestedLoop
You now have nested loops explicitly coded, but these are 1-trip loops unless otherwise desired. Note that if you intend to construct arrays of rank that depends on the nested loop depth, you can go up to rank of 7, or 15 if you have a compiler that supports it (Fortran 2008). You can now try:
call nestedLoop([1])
call nestedLoop([2,3])
call nestedLoop([1,2,3,2,1])
You can modify this routine to your liking and desired applicability, add exception handling etc.
From an OOP approach, each loop could be represented by a "Loop" object - this object would have the ability to be constructed while containing another instance of itself. You could then theoretically nest these as deep as you need to.
Loop1 would execute Loop2 would execute Loop3.. and onwards.
What is the most concise way of converting a java.util.List into a normal
JavaFX sequence (in JavaFX)?
e.g.
def myList = java.util.Arrays.asList(1, 2, 3);
def mySequence = ... // a sequence containing [1, 2, 3]
This is the most concise way I could find - there may be a more direct method though
def myList = java.util.Arrays.asList(1, 2, 3);
def mySequence = for (i in myList) i;
println("mySequence={mySequence}");