# Base operator on custom array

**URL:** https://discourse.julialang.org/t/base-operator-on-custom-array/83042
**Category:** New to Julia
**Created:** [June 20, 2022, 4:03am UTC](https://discourse.julialang.org/t/base-operator-on-custom-array/83042 "2022-06-20T04:03:53Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![Brian1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brian1/32/49250_2.png) [@Brian1](https://discourse.julialang.org/u/Brian1)
#### Post date: [June 20, 2022, 4:03am UTC](https://discourse.julialang.org/t/base-operator-on-custom-array/83042/1 "2022-06-20T04:03:53Z")

</div>

Here I define a struct

```julia

struct Df{T,N} <: AbstractArray{T,N}
    value::AbstractArray{T,N}
end

Base.size(df::Df)=size(df.value)

Base.getindex(df::Df,i...)=Df(df.value[i...])
Base.getindex(df::Df,i::Union{Int,CartesianIndex}...)=df.value[i...]
Base.eachindex(df::Df)=eachindex(df.value)

-> df=Df([[1,2,3] [2,3,4]])

3×2 Df{Int64, 2}:
 1 2
 2 3
 3 4

```

Then, I can apply `Base` operator ( like `+ -` ) on `df`

```julia
-> df .+ 1

3×2 Matrix{Int64}:
 2 3
 3 4
 4 5

```

But the result is a `Matrix` rather than a `Df`. The expected result would like:

```julia
-> df .+ 1

3×2 Df{Int64, 2}:
 2 3
 3 4
 4 5

```

What am I missing here?

---

<div class="post-metadata">

### Author: ![skleinbo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skleinbo/32/36080_2.png) [@skleinbo](https://discourse.julialang.org/u/skleinbo)
#### Post date: [June 20, 2022, 5:20am UTC](https://discourse.julialang.org/t/base-operator-on-custom-array/83042/2 "2022-06-20T05:20:08Z")

</div>

You need to define a few methods for broadcasting. The example at the end of [Interfaces · The Julia Language](https://docs.julialang.org/en/v1/manual/interfaces/#man-interfaces-broadcasting) is ver close to what you want.

---

<div class="post-metadata">

### Author: ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)
#### Post date: [June 20, 2022, 5:20am UTC](https://discourse.julialang.org/t/base-operator-on-custom-array/83042/3 "2022-06-20T05:20:25Z")

</div>

You’ll also need to implement the broadcasting API to preserve the matrix type: [Interfaces · The Julia Language](https://docs.julialang.org/en/v1/manual/interfaces/#man-interfaces-broadcasting)

Edit: what @skleinbo said 🙂

---

<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: [June 20, 2022, 7:21am UTC](https://discourse.julialang.org/t/base-operator-on-custom-array/83042/4 "2022-06-20T07:21:35Z")

</div>

> [@Brian1](#):
>
> ```julia
> struct Df{T,N} <: AbstractArray{T,N}
> value::AbstractArray{T,N}
> end
> 
> ```

Abstract field types are very bad for performance. It’s normally better to either just wrap `Array{T, N}` or make the wrapped array type a type parameter for `Df`.

---

<div class="post-metadata">

### Author: ![Brian1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brian1/32/49250_2.png) [@Brian1](https://discourse.julialang.org/u/Brian1)
#### Post date: [June 20, 2022, 7:53am UTC](https://discourse.julialang.org/t/base-operator-on-custom-array/83042/6 "2022-06-20T07:53:50Z")

</div>

Thanks for your advice. I have changed it to this:

```julia
struct Df{K,T,N,D,C} <: AbstractArray{T,N}
    index::Vector{K}
    value::C
    column::D
    Df{K,T,N,D,C}(index::Vector{K},value::AbstractArray{T,N},column::D=nothing) where {K,T,N,D,C}=
            new{K,T,N,D,C}(index,value,column)
end

```

Would it be better, right?

---

<div class="post-metadata">

### Author: ![Brian1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brian1/32/49250_2.png) [@Brian1](https://discourse.julialang.org/u/Brian1)
#### Post date: [June 20, 2022, 8:08am UTC](https://discourse.julialang.org/t/base-operator-on-custom-array/83042/7 "2022-06-20T08:08:26Z")

</div>

Yes, the example is very close. Thanks very much for your help.
