# Robust method of modifying corners of an Array

**URL:** <https://discourse.julialang.org/t/robust-method-of-modifying-corners-of-an-array/31398>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [November 22, 2019, 8:37pm UTC](https://discourse.julialang.org/t/robust-method-of-modifying-corners-of-an-array/31398 "2019-11-22T20:37:18Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![jonathan-durbin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jonathan-durbin/32/11468_2.png) [@jonathan-durbin](https://discourse.julialang.org/u/jonathan-durbin)\
**Post date:** [November 22, 2019, 8:37pm UTC](https://discourse.julialang.org/t/robust-method-of-modifying-corners-of-an-array/31398/1 "2019-11-22T20:37:19Z")

</div>

I’m trying to write a simple function that replaces the corners of an array with a value. This is what I have so far:

```julia
function replaceCorners!(a::AbstractArray{String, 2}, v::String)
    a[1, 1] = a[1, size(a)[2]] = a[size(a)[1], 1] = a[size(a)...] = v
end

```

I have a few questions about this problem, especially because I’m new to Julia.

1. Is this the most “julian” way to replace the corners of an array?
2. This method works for an array that looks like `["a" "b" "c"]`, but not for an array such as `["a"; "b"; "c"]`. How can I make it work for arrays of any size?
3. In the function above, I only allowed for arrays that contain strings and values that are strings - how would I go about making this applicable to any type?

Thanks in advance for your suggestions!

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [November 22, 2019, 8:42pm UTC](https://discourse.julialang.org/t/robust-method-of-modifying-corners-of-an-array/31398/2 "2019-11-22T20:42:18Z")

</div>

> [@jonathan-durbin](#):
>
> I only allowed for arrays that contain strings and values that are strings - how would I go about making this applicable to any type?

```julia
replaceCorners!(a::AbstractArray{T, 2}, v::T) where T

```

also, reuse `size(a)`

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [November 22, 2019, 8:42pm UTC](https://discourse.julialang.org/t/robust-method-of-modifying-corners-of-an-array/31398/3 "2019-11-22T20:42:41Z")

</div>

For question 3, the corredt way is to have the function be `function replaceCorners!(a::AbstractMatrix{T}, v::T) where T`

---

<div class="post-metadata">

**Author:** ![jonathan-durbin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jonathan-durbin/32/11468_2.png) [@jonathan-durbin](https://discourse.julialang.org/u/jonathan-durbin)\
**Post date:** [November 22, 2019, 8:48pm UTC](https://discourse.julialang.org/t/robust-method-of-modifying-corners-of-an-array/31398/4 "2019-11-22T20:48:21Z")

</div>

> [@jling](#):
>
> also, reuse `size(a)`

Do you mind clarifying on this? From what I can tell, I am reusing `size(a)` in the function.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [November 22, 2019, 8:56pm UTC](https://discourse.julialang.org/t/robust-method-of-modifying-corners-of-an-array/31398/5 "2019-11-22T20:56:27Z")

</div>

my bad, I think in this inline case `size` only gets evaluated once.

---

<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:** [November 22, 2019, 9:03pm UTC](https://discourse.julialang.org/t/robust-method-of-modifying-corners-of-an-array/31398/6 "2019-11-22T21:03:11Z")

</div>

Here’s a simple solution for doing this in general.

```nohighlight
firstlast(x) = first(x):length(x)-1:last(x)
function replace_corners!(a::AbstractArray, v)
    a[firstlast.(axes(a))...] .= (v,)
    return a
end

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [November 22, 2019, 9:24pm UTC](https://discourse.julialang.org/t/robust-method-of-modifying-corners-of-an-array/31398/7 "2019-11-22T21:24:54Z")

</div>

Are you aware that you can use `end`?

```julia
function repcorners!(a, v)
    a[1, 1] = a[1, end] = a[end, 1] = a[end, end] = v
end

```

This is less general than @mbauman’s solution, but it’s the obvious implementation of what you are doing.

Also, it is more idiomatic to write `size(a, 1)` than `size(a)[1]`.

---

<div class="post-metadata">

**Author:** ![jonathan-durbin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jonathan-durbin/32/11468_2.png) [@jonathan-durbin](https://discourse.julialang.org/u/jonathan-durbin)\
**Post date:** [November 22, 2019, 9:36pm UTC](https://discourse.julialang.org/t/robust-method-of-modifying-corners-of-an-array/31398/8 "2019-11-22T21:36:12Z")

</div>

Thanks for the alternative solution! I’m having some trouble figuring out what exactly is happening on the third line.

With an example array like this

```julia
a = [
    12 11 10 9;
    8 7 6 5;
    4 3 2 1;
]

```

Running `firstlast.(axes(a))` gives me `(1:2:3, 1:3:4)`. This makes sense, but splatting that then indexing a by the result is hard to visualize. Secondly, what is the significance of using `(v,)`?

---

<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:** [November 22, 2019, 9:46pm UTC](https://discourse.julialang.org/t/robust-method-of-modifying-corners-of-an-array/31398/9 "2019-11-22T21:46:42Z")

</div>

I actually had the following at first (before a ninja edit):

```julia
firstlast(x) = [first(x), last(x)]

```

That is, I just want an array with two elements. The above isn’t ideal because it’ll actually allocate an `Array` for every dimension. I swapped to a cleverly constructed StepRange that contains the same elements — but will probably avoid allocations entirely.

So I splat that into the array, which effectively does:

```julia
a[[1,end],[1,end],[1,end], #=etc=#]

```

This selects the cartesian product of all the endpoints of each dimension in the array. For a two-dimensional array, there are 4 (`2*2`) corners. A cube has 8 (`2*2*2`). And so on.

Then I _broadcast_ the value `v` into all those locations I’ve selected. If `v` itself is broadcastable container, well, then it’ll try to match its shape with the shape of the indices I used — potentially “spreading” its values out amongst the selected locations (but more likely just throwing a shape mismatch error). Using `(v,)` “protects” the value inside a container I _know_ is only one element and ensures that `v` itself is assigned to each and every single chosen location.

Also note that I’m not restricting the type of `v` at all. Upon assignment, Julia will attempt to `convert` v to the element type of the array for you — and it’ll happily throw an error at that point if it’s not possible.

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [November 23, 2019, 2:37pm UTC](https://discourse.julialang.org/t/robust-method-of-modifying-corners-of-an-array/31398/10 "2019-11-23T14:37:38Z")

</div>

FWIW, ImageTransformations has [CornerIterator](https://github.com/JuliaImages/ImageTransformations.jl/blob/de5a14d81ba445eea5cd36075e7b588d796d5103/src/autorange.jl#L20-L64)
