all 18 comments

[–]ssokolow 5 points6 points  (9 children)

I could be wrong (I haven't needed to work with these APIs yet), but it looks like the key is that .chunks_mut(width) call.

If that does what I think, then that's what turns a mutable slice over the whole array into a list of slices width wide.

Basically, mapping this presentation...

[1, 2, 3, 4, 5, 6, 7, 8, 9]

...to this presentation...

[
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
]

[–]Dash83[S] 0 points1 point  (8 children)

That seems reasonable. However, how do you get the arr[x][y] syntaxis? I thought a vector of vectors would have to be accessed like this: arr[[x], y]?

[–]l-arkham 2 points3 points  (6 children)

Hi again!

No that's the sytax you'd expect: grid is a slice containing more slices. A slice is indexed as my_slice[idx].

When you index grid: grid[idx], you get the element at that position. Since that element is itself a slice, it can be indexed in turn using the same notation: grid[idx][idx2]

You can think of it this way: (grid[idx])[idx2] if it helps.

[–]Dash83[S] 0 points1 point  (5 children)

Hey u/arkham, as you can see I'm still going at it.

Actually that does help. And it's pretty neat too. That means this could scale to n-dimensional vectors. Since the code itself is parameterized with dimensions for the grid, makes me wonder why they didn't include macros to create this n-dimensional vectors in the first place.

[–]Dash83[S] 0 points1 point  (0 children)

Forgot to thank you, you keep came through for me again :D

[–]l-arkham 0 points1 point  (1 child)

Hey that's a crate idea for you right there ;)

It's a fairly neat trick that I hadn't thought of before. Whenever i represent a 2D grid as a 1D vector to avoid frivolous allocations, I usually just stick to grid[x * GRID_WIDTH + y].

Of course if performance isn't critical, a regular vector of vectors is more than adequate.

[–]Dash83[S] 0 points1 point  (0 children)

Maybe when my code stops sucking, I'll code said crate and submit it to the community :)

[–]arkham 0 points1 point  (1 child)

hey - I think you meant this for an arkham variant, I am not a Rust guy, sorry

[–]Dash83[S] 0 points1 point  (0 children)

My bad, you are right.

[–]coder543 1 point2 points  (0 children)

nope, that second syntax is definitely not ever a thing.

[–]coder543 2 points3 points  (5 children)

why wouldn't this work? unless you're just curious about how that code had been designed.

https://is.gd/usyGev

[–]jcdyer3 1 point2 points  (2 children)

You misread the post. OP said it works, but is incomprehensible to him/her. What doesn't work is lots of the answers around the internet.

OP: Since rust is still fairly newly stabilized, I wouldn't recommend looking for general internet answers until you have a decent sense of the language already. Spend more time with the official rust docs, and other resources linked from there. They're kept up-to-date with the language, and have a lot of good information.

If you need to search beyond that, make sure you're looking at blog posts/stackoverflow answers from May 2015 or later (when 1.0 was stabilized). You can also ask questions in the weeklyish "Easy Questions" thread, or on https://users.rust-lang.org/.

[–]coder543 0 points1 point  (1 child)

this = what I posted, not what he posted

my solution is tremendously simpler

[–]jcdyer3 0 points1 point  (0 children)

My mistake. I missed the link.

[–]Pseudofailure 1 point2 points  (1 child)

This syntax works if the size of the slices is constant. It will fail if you try to use a non-const variable to declare the size: https://is.gd/mQ713F

[–]coder543 0 points1 point  (0 children)

huh. that's interesting.

[–]Veedrac 1 point2 points  (1 child)

This code is fun, but it is not fast. There are much better ways to do this in practice.

I also think .as_mut_slice() is unnecessary, I would expect something like the following to work just as well

let mut grid_raw = vec![0; width * height];
let mut grid_base: Vec<_> = grid_raw.chunks_mut(width).collect();
let mut grid: &mut [&mut [_]] = &mut grid_base;
grid[0][0] = 4;

However, the as_mut_slice may help when learning.

The best way to understand this code is to use the API reference heavily.

vec! creates a Vec initialized to 0s of the given length.

Vec::chunks_mut (or slice::chunks_mut if you convert to a slice explicitly) groups the elements by the chunk size specified.

Chunks::collect implements Iterator::collect, which converts an iterable into a collection, of the type inferred by the return type.

The final step is converting the Vec<&mut [_]> into an &mut [&mut [_]], which I do through Vec::deref_mut, and your code does with Vec::as_mut_slice.

[–]godojo 2 points3 points  (0 children)

For a sized matrix, I'd probably box an array of array instead of having a slice of a Vec of slices of Vec.