# Undoing a view

**URL:** <https://discourse.julialang.org/t/undoing-a-view/103996>\
**Category:** General Usage\
**Created:** [September 18, 2023, 5:31pm UTC](https://discourse.julialang.org/t/undoing-a-view/103996 "2023-09-18T17:31:24Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)\
**Post date:** [September 18, 2023, 5:31pm UTC](https://discourse.julialang.org/t/undoing-a-view/103996/1 "2023-09-18T17:31:24Z")

</div>

`view(b, ixs)` creates a view that references the original storage `a`, rather than the intermediate view `b`. I am interested in getting the argument `b` back out of `c`, undoing the second slice.

Is there something like either

- a “hard view” `b`, views of which remember they came from `b`?
- a “shallow view” `@shallowview` that remembers it came from `b`?

```julia
julia> a = [10,20,30,40]
4-element Vector{Int64}:
 10
 20
 30
 40

julia> b = @view a[2:end]
3-element view(::Vector{Int64}, 2:4) with eltype Int64:
 20
 30
 40

julia> c = @view b[2:end]
2-element view(::Vector{Int64}, 3:4) with eltype Int64:
 30
 40

julia> dump(c)
SubArray{Int64, 1, Vector{Int64}, Tuple{UnitRange{Int64}}, true}
  parent: Array{Int64}((4,)) [10, 20, 30, 40]
  indices: Tuple{UnitRange{Int64}}
    1: UnitRange{Int64}
      start: Int64 3
      stop: Int64 4
  offset1: Int64 2
  stride1: Int64 1

```

---

<div class="post-metadata">

**Author:** ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)\
**Post date:** [September 18, 2023, 5:42pm UTC](https://discourse.julialang.org/t/undoing-a-view/103996/2 "2023-09-18T17:42:43Z")

</div>

```julia
julia> parent(c)
4-element Vector{Int64}:
 10
 20
 30
 40

```

EDIT: Sorry, think I misunderstood what you wanted…

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [September 18, 2023, 5:42pm UTC](https://discourse.julialang.org/t/undoing-a-view/103996/3 "2023-09-18T17:42:47Z")

</div>

Not builtin, no. The builtin subarray does all sorts of magic with the indices (and even the parent) such that you cannot reliably ask these questions of the builtin views.

But this could definitely be a package. This kind of “index-forward” or “process-oriented” mental model where the exact parent & indices matter just as much (or more) than the data they select is a very different view (pun intended) than the builtin takes.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [September 18, 2023, 8:09pm UTC](https://discourse.julialang.org/t/undoing-a-view/103996/4 "2023-09-18T20:09:48Z")

</div>

> [@jar1](#):
>
> Is there either something like
> 
> - a “hard view” `b`, views of which remember they came from `b`?

You can make this by calling the `SubArray` constructor explicitly, rather than via `view`:

```julia
julia> c2 = SubArray(b, (2:lastindex(b),))
2-element view(view(::Vector{Int64}, 2:4), 2:3) with eltype Int64:
 30
 40

julia> dump(c2)
SubArray{Int64, 1, SubArray{Int64, 1, Vector{Int64}, Tuple{UnitRange{Int64}}, true}, Tuple{UnitRange{Int64}}, true}
  parent: SubArray{Int64, 1, Vector{Int64}, Tuple{UnitRange{Int64}}, true}
    parent: Array{Int64}((4,)) [10, 20, 30, 40]
    indices: Tuple{UnitRange{Int64}}
      1: UnitRange{Int64}
        start: Int64 2
        stop: Int64 4
    offset1: Int64 1
    stride1: Int64 1
  indices: Tuple{UnitRange{Int64}}
    1: UnitRange{Int64}
      start: Int64 2
      stop: Int64 3
  offset1: Int64 1
  stride1: Int64 1

```

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [September 18, 2023, 9:08pm UTC](https://discourse.julialang.org/t/undoing-a-view/103996/5 "2023-09-18T21:08:29Z")

</div>

True! I had forgotten where we had put all the indexing jiggery-pokery; it’s in `view`, not in the constructor. On the flip side, it doesn’t do indexing jiggery-pokery, so caller beware:

- No bounds checks
- No support for linear or logical indexing
- No support for CartesianIndex or other non-integer (or non-array-of-integer) indices

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [September 19, 2023, 8:38am UTC](https://discourse.julialang.org/t/undoing-a-view/103996/6 "2023-09-19T08:38:24Z")

</div>

> [@mbauman](#):
>
> caller beware

Also the constructor is not described in the `SubArray` doc string, which however says that `view` is the intended way of constructing `SubArray` values. Giving the impression that the `SubArray` constructor may not be a stable interface.
