Hello I am trying to create a 2D vector in rust simply by making a vector of vectors and then printing it in a 2D form.
Code:
fn draw_grid(grid:&Vec<Vec<i32>>){
for r in 0..grid.len(){
for c in 0..grid.len(){
print!("{}", grid[r[c]]);
}
}
error:
error[E0608]: cannot index into a value of type `usize`
As you can see the compiler doesn't like it when I try to index it like a normal vector. Your help is greatly appreciated :)
You aren't indexing a vector, you are indexing an integer.
for r in 0..grid.len() {
// r is an integer here
for c in 0..grid.len() {
// yet you are trying to index it as if it were an array: r[c]
print!("{}", grid[r[c]]);
}
}
The simple fix is to do print!("{}", grid[r][c]);.
However, the idiomatic way to iterate a vector in Rust is this:
for r in grid {
for c in r {
print!("{}", c);
}
}
You're looking for grid[r][c].
grid is your vector of vector.
grid[r] is the r-th row, which is itself a vector.
grid[r][c], which can be seen as (grid[r])[c] if that helps, is element on the c-th column of that row.
Related
i was wondering if there is as faster way to check if given data is a vector or a matrix with zero rows or not, rather than,
if (is.vector(x)){
print('vector')
} else if {nrow(x) == 0){
print('0 rows')
} else {
print('matrix').
}
I am only interested in finding matrices fast.
Thanks a lot.
One method would be to use dim:
!is.null(dim(x)) && all(dim(x)>0)
If x is a vector, dim(x) is NULL.
I am not sure if this is faster than your own method and also not sure if this is a computation-intensive task at all.
I have a 2D array of Strings, and I'm trying to pass it to a function as a parameter. I successfully have done this with a 2D array of i32, but with Strings I've had no luck.
An example array:
let my_string_array_2d = [
["Two", "Arrays", "Of"],
["Three", "Strings", "Each"]
];
Here is the function I'm using for a 2d Array of i32:
fn print2DIntArray<Matrix: AsRef<[Row]>, Row: AsRef<[i32]>>(x: Matrix) {
for row in x.as_ref() {
for cell in row.as_ref() {
print!("{} ", cell);
}
println!("");
}
}
I've tried replacing i32 with String, str and &str with no luck. I'm not a Rust developer, so it could be something simple I'm missing.
I know I can do it with a fixed dimension but I'm trying to find a generic solution.
Thanks in advance for any help.
You were on the right track - the inner items are string slices, so &str is the correct type. However you needed to add a lifetime annotation:
fn print_2d_int_array<'a, Matrix: AsRef<[Row]>, Row: AsRef<[&'a str]>>(x: Matrix)
Playground Link
You could make it even more generic in this case: if the objective is to be able to print the matrix, you just need to constrain the cells to be Display:
use std::fmt::Display;
fn print_2d_int_array<Matrix: AsRef<[Row]>, Row: AsRef<[P]>, P: Display>(x: Matrix)
Let's say I have the following code:
fn extract() -> Vec<String> {
let data = vec!["aaa".to_string(), "bbb".to_string(), "ccc".to_string()];
vec![data[0], data[2]]
}
In practice, I read data from a file.
Obviously, this doesn't compile because I'm pulling strings out of the vector data, leaving the vector in an undefined state. But, conceptually, it should work, because I'm not using data afterwards anyway.
I can use mem::replace, but this seems crazy:
fn extract() -> Vec<String> {
let mut data = vec!["aaa".to_string(), "bbb".to_string(), "ccc".to_string()];
let a = mem::replace(&mut data[0], "".to_string());
let c = mem::replace(&mut data[2], "".to_string());
vec![a, c]
}
How do I go about extracting specific elements from the vector without having to clone the strings?
Vec has special methods for that. swap_remove, remove (warning, linear complexity), drain. For example,
fn extract() -> Vec<String> {
let mut data = vec!["aaa".to_string(), "bbb".to_string(), "ccc".to_string()];
// order does matter
vec![data.swap_remove(2), data.swap_remove(0)]
}
You cannot have "holes" in a vector. So when you move something out of it, you either change the indices of the remaining elements (using remove or swap_remove), or replace it with something else.
Why don't you just consume the vector in order and ignore what you don't need? If you need to save some of the elements for later use, you can use data.iter().filter(...).collect(). If you really want to avoid copying any strings, you can wrap them in Rc so that only pointers are copied.
can somebody explain why for loops are executed even on variables with zero length? For example
listFunction<-function(listinput)
{
for (i in 1:length(listinput))
{listinput[i]<-listinput[i]+1
print("googats")
}
listinput
}
listB<-c()
listFunction(listB)
[1] "googats"
[1] "googats"
> listB
NULL
why does it iterate the loop twice rather than simply not go in at all?
Per official documentation, for loop
The syntax of the for loop is
for ( name in vector )
statement1
where vector can be either a
vector or a list. For each element in vector the variable name is set
to the value of that element and statement1 is evaluated. A side
effect is that the variable name still exists after the loop has
concluded and it has the value of the last element of vector that the
loop was evaluated for.
So, it will iterate through each element.
In your case,
for (i in 1:length(listinput))
{
listinput[i]<-listinput[i]+1
print("googats")
}
is like
for (i in 1:0)
{
listinput[i]<-listinput[i]+1
print("googats")
}
since there are 2 elements 1 and 0 in your vector, the loop body will be iterated twice.
can please somebody tell me how I can call my output which are two matrices as an input into another function?
X1=function(y,z)
{
output1=y*z
output2=y/z
}
X2=function(p,q)
{
input=X1(y,z)
input1=input$output1 ??? How to specify the output that I can call it this way? output1 and output2 are matrices!
input2=input$output2
equation=input1+input2
}
I tried return() and data.frame but both didn't work. Any tipps?
You can't use c as some might otherwise expect because you'll lose the structure of the matrices. Instead, use list when you want to return multiple objects from an R function.
X1 <- function(y,z)
{
list(
output1=y*z,
output2=y/z
)
}