# Special case handling - alternatives to if/else?

**URL:** https://discourse.julialang.org/t/special-case-handling-alternatives-to-if-else/21608
**Category:** Data
**Tags:** question, data, dataframes
**Created:** [March 7, 2019, 10:14pm UTC](https://discourse.julialang.org/t/special-case-handling-alternatives-to-if-else/21608 "2019-03-07T22:14:48Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![kevbonham](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kevbonham/32/216165_2.png) [@kevbonham](https://discourse.julialang.org/u/kevbonham)
#### Post date: [March 7, 2019, 10:14pm UTC](https://discourse.julialang.org/t/special-case-handling-alternatives-to-if-else/21608/1 "2019-03-07T22:14:48Z")

</div>

I have an unruly and monster data table from collaborators, and I’m writing a script to clean it up. The table is updated on a semi-regular basis, and there’s no option to get it in a better form, so I’m stuck trying to write a workaround. The table has a number of subtables, which are indicated in the header, so for example I might have

| A1 | A2 | A3 | B1 | B2 | … | Z5 | |
| --- | --- | --- | --- | --- | --- | --- | --- |
| foo | 1.3 | “a” | | | | | |
| foo | 2.4 | “b” | | | | | |
| bar | 1.7 | “a” | | | | | |
| baz | 3.3 | “a” | | | | | |
| | | | foo | 8.2 | | | |
| | | | foo | 9.2 | | | |
| | | | baz | 10. | | | |
| … | … | … | … | … | … | … | |
| | | | | | | “stuff” | |

And I need to process all the `A` columns together, all the `B` columns together etc. So I’ve got code that splits the table by the header, does some processing and then converts things to long form etc.

All of this works great - the question comes from the fact that, while 80% of the subtables can be processed with the same code, about 20% of them need some idiosyncratic stuff. I’ve started off doing:

```julia
const special_cases = Set(["B", "E", "Q"])

function customprocess!(table, parent)
    !in(parent, special_cases) && return table

    if parent == "B"
        # Custom code for B
    elseif parent == "E"
        # Custom code for E
    elseif parent == "Q"
        # Custom code for Q
    end
    return table
end

```

This works, but as my number of special cases is increasing, this feels very unwieldy. And this is a project where the table will keep getting updated and the script will keep getting used potentially for years, so I’d like something that’s a bit more maintainable than a giant if-else. Is there a good way to use multiple dispatch or some other sort of design pattern to make the code a bit more readable/maintainable?

I was thinking something like

```julia
abstract type AbstractParentTable end

struct ParentB <: AbstractParentTable end
struct ParentE <: AbstractParentTable end
struct ParentQ <: AbstractParentTable end

```

And then define different methods for these, but I wasn’t sure how to get a type of `ParentB` (for example) from the `"B"` in the header. Other ideas welcome.

---

<div class="post-metadata">

### Author: ![yurivish](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yurivish/32/307_2.png) [@yurivish](https://discourse.julialang.org/u/yurivish)
#### Post date: [March 7, 2019, 10:22pm UTC](https://discourse.julialang.org/t/special-case-handling-alternatives-to-if-else/21608/2 "2019-03-07T22:22:57Z")

</div>

Could you use a `Dict` that maps `"B"` to `ParentB`?

---

<div class="post-metadata">

### Author: ![kevbonham](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kevbonham/32/216165_2.png) [@kevbonham](https://discourse.julialang.org/u/kevbonham)
#### Post date: [March 7, 2019, 11:10pm UTC](https://discourse.julialang.org/t/special-case-handling-alternatives-to-if-else/21608/3 "2019-03-07T23:10:01Z")

</div>

Yeah, that’s certainly doable. I could make `special_cases` a dict and then do `haskey()` instead of `in()`.

Can’t tell if that’s actually simpler though… I guess keeping the function definitions separate is still nicer. Would like a way to do it more dynamically though, maybe with a macro?

---

<div class="post-metadata">

### Author: ![kirtsar](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kirtsar/32/7222_2.png) [@kirtsar](https://discourse.julialang.org/u/kirtsar)
#### Post date: [March 7, 2019, 11:25pm UTC](https://discourse.julialang.org/t/special-case-handling-alternatives-to-if-else/21608/4 "2019-03-07T23:25:26Z")

</div>

It looks like a use-case for Value types: [Types · The Julia Language](https://docs.julialang.org/en/v1/manual/types/#%22Value-types%22-1)

---

<div class="post-metadata">

### Author: ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)
#### Post date: [March 7, 2019, 11:31pm UTC](https://discourse.julialang.org/t/special-case-handling-alternatives-to-if-else/21608/5 "2019-03-07T23:31:58Z")

</div>

> [@kirtsar](#):
>
> It looks like a use-case for Value types

Yes, this is exactly what I thought, too.

To elaborate on the idea, would something like this work for you?

```julia
# Value type
struct Col{T}
end
Col(s::String) = Col{Symbol(s)}()

# Default behaviour: do nothing
process!(table, ::Col) = nothing

# Custom behaviour for column header "A": add 10 to every cell
process!(table, ::Col{:A}) = foreach(eachindex(table)) do i
    table[i] += 10
end

```

```julia
julia> # Sample data
       table = Dict("A" => [1,2,3], 
                    "B" => [4,5,6])
Dict{String,Array{Int64,1}} with 2 entries:
  "B" => [4, 5, 6]
  "A" => [1, 2, 3]

julia> # Process everything
       for key in keys(table)
           process!(table[key], Col(key))
       end

julia> table
Dict{String,Array{Int64,1}} with 2 entries:
  "B" => [4, 5, 6]
  "A" => [11, 12, 13]

```

---

<div class="post-metadata">

### Author: ![kevbonham](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kevbonham/32/216165_2.png) [@kevbonham](https://discourse.julialang.org/u/kevbonham)
#### Post date: [March 7, 2019, 11:49pm UTC](https://discourse.julialang.org/t/special-case-handling-alternatives-to-if-else/21608/6 "2019-03-07T23:49:20Z")

</div>

> [@ffevotte](#):
>
> To elaborate on the idea, would something like this work for you?

Oh yeah - this looks like exactly what I need, thanks! (to @kirtsar too). I’ll check out the docs and give that a spin.
