# Is there a coalesce function for other types?

**URL:** <https://discourse.julialang.org/t/is-there-a-coalesce-function-for-other-types/60112>\
**Category:** General Usage\
**Tags:** question, data\
**Created:** [April 27, 2021, 3:22pm UTC](https://discourse.julialang.org/t/is-there-a-coalesce-function-for-other-types/60112 "2021-04-27T15:22:48Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![feanor12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/feanor12/32/8212_2.png) [@feanor12](https://discourse.julialang.org/u/feanor12)\
**Post date:** [April 27, 2021, 3:22pm UTC](https://discourse.julialang.org/t/is-there-a-coalesce-function-for-other-types/60112/1 "2021-04-27T15:22:48Z")

</div>

I found this nice function called `coalesce` and now I am wondering if there is a more general one. Is there a function like coalesce which can specify the missing value/type.

```julia
a = [NaN,missing,"",2,3.0]
coalesce.(a,0)
coalesce.(a,0,missing="") # fails
coalesce.(a,0,missing=NaN) # fails

```

Update: A good solution might be:

```julia
clean(a,junk,target) = identity.(replace(a, (junk .=> target)...))
clean(a,["",missing,NaN],0)

```

---

<div class="post-metadata">

**Author:** ![thisrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thisrod/32/10642_2.png) [@thisrod](https://discourse.julialang.org/u/thisrod)\
**Post date:** [April 28, 2021, 1:45am UTC](https://discourse.julialang.org/t/is-there-a-coalesce-function-for-other-types/60112/2 "2021-04-28T01:45:21Z")

</div>

> [@feanor12](#):
>
> I am wondering if there is a more general one

It’s a one-liner:

```
julia> [isequal(x, "") ? 0 : x for x in a]
5-element Array{Any,1}:
 NaN
    missing
   0
   2
   3.0

```

You could easily write a function to do this if you wished.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [April 28, 2021, 7:27am UTC](https://discourse.julialang.org/t/is-there-a-coalesce-function-for-other-types/60112/3 "2021-04-28T07:27:32Z")

</div>

I think `replace(a, NaN => 0)` is what you are looking for. For multiple replacements: `replace(a, NaN => 0, missing => 0, "" => 0)`.  
Unfortunately, the result still has type `Vector{Any}` instead of `Vector{Float64}`.

---

<div class="post-metadata">

**Author:** ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)\
**Post date:** [April 28, 2021, 8:07am UTC](https://discourse.julialang.org/t/is-there-a-coalesce-function-for-other-types/60112/4 "2021-04-28T08:07:51Z")

</div>

You can use `identity` to try an narrow the type after replacing, although in this case you’ll only get `Real` as there are Int and Float in the vector:

```julia
julia> identity.(replace(a, ([NaN, missing, ""] .=> 0.0)...))
5-element Vector{Real}:
 0.0
 0.0
 0.0
 2
 3.0

```

---

<div class="post-metadata">

**Author:** ![feanor12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/feanor12/32/8212_2.png) [@feanor12](https://discourse.julialang.org/u/feanor12)\
**Post date:** [April 28, 2021, 10:27am UTC](https://discourse.julialang.org/t/is-there-a-coalesce-function-for-other-types/60112/5 "2021-04-28T10:27:21Z")

</div>

I like the trick of using identity to narrow down the type. 👍  
Is this the common way of narrowing down an array type?

```julia
clean(a,junk,target) = identity.(replace(a, (junk .=> target)...))
clean(a,["",missing],0)

```

---

<div class="post-metadata">

**Author:** ![rfourquet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rfourquet/32/3610_2.png) [@rfourquet](https://discourse.julialang.org/u/rfourquet)\
**Post date:** [April 28, 2021, 10:57am UTC](https://discourse.julialang.org/t/is-there-a-coalesce-function-for-other-types/60112/6 "2021-04-28T10:57:45Z")

</div>

Just a note to say that for singleton types, `replace` is able by itself to narrow the eltype:

```julia
julia> a = [missing, 1.1, NaN, nothing]
4-element Vector{Union{Missing, Nothing, Float64}}:
    missing
   1.1
 NaN
    nothing

julia> replace(a, NaN => 0, missing => 0, nothing => 0)
4-element Vector{Float64}:
 0.0
 1.1
 0.0
 0.0

```

---

<div class="post-metadata">

**Author:** ![feanor12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/feanor12/32/8212_2.png) [@feanor12](https://discourse.julialang.org/u/feanor12)\
**Post date:** [April 28, 2021, 1:21pm UTC](https://discourse.julialang.org/t/is-there-a-coalesce-function-for-other-types/60112/7 "2021-04-28T13:21:57Z")

</div>

I think this only works if the original vector is a Union and not of type Any

---

<div class="post-metadata">

**Author:** ![rfourquet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rfourquet/32/3610_2.png) [@rfourquet](https://discourse.julialang.org/u/rfourquet)\
**Post date:** [April 28, 2021, 3:08pm UTC](https://discourse.julialang.org/t/is-there-a-coalesce-function-for-other-types/60112/8 "2021-04-28T15:08:29Z")

</div>

Indeed, `replace` allocates the final vector before going through the elements. So the “type narrowing” is done only using the initial type of the vector and the replacement pairs (e.g. for `eltype(a) == Union{Missing, Float64}` and pair `missing => 0.0` , it’s possible to determine before any pass on the source vector that the destination vector will have eltype `Float64` ).

---

<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:** [April 28, 2021, 3:55pm UTC](https://discourse.julialang.org/t/is-there-a-coalesce-function-for-other-types/60112/9 "2021-04-28T15:55:47Z")

</div>

I often broadcast `ifelse` in situations like this:

```julia
julia> @. ifelse(ismissing(a) || a == "" || isnan(a), 0.0, a)
5-element Vector{Real}:
 0.0
 0.0
 0.0
 2
 3.0

```

Ok, that only works on Julia 1.7, but I’m seriously excited that it works on 1.7!

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [April 28, 2021, 4:09pm UTC](https://discourse.julialang.org/t/is-there-a-coalesce-function-for-other-types/60112/10 "2021-04-28T16:09:40Z")

</div>

This is excellent! Was not aware this was merged.

It sounds like the main “conditional evaluation” problem was solved. Does that mean we can expect to see broadcasted `? :` in the future?

---

<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:** [April 28, 2021, 4:41pm UTC](https://discourse.julialang.org/t/is-there-a-coalesce-function-for-other-types/60112/11 "2021-04-28T16:41:55Z")

</div>

Unfortunately `? :` is a bit different — it’s parsed _directly_ to an `if` statement.

```julia
julia> Meta.parse("a ? b : c")
:(if a
      b
  else
      c
  end)

```

So that’s why we didn’t deprecate its use within `@.` expressions like we did `||` and `&&` long ago (which is what made space for the above). Making arbitrary `if` clauses participate in broadcast is a much bigger thing.

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [April 28, 2021, 6:21pm UTC](https://discourse.julialang.org/t/is-there-a-coalesce-function-for-other-types/60112/12 "2021-04-28T18:21:54Z")

</div>

I’m curious why `? :` goes to `if else` rather than `ifelse`?

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [April 28, 2021, 6:30pm UTC](https://discourse.julialang.org/t/is-there-a-coalesce-function-for-other-types/60112/13 "2021-04-28T18:30:10Z")

</div>

`ifelse(x, a(), b())` will evaluate both `a()` and `b()`, whereas `x ? a() : b()` will not. So the parsing of `? :` is for performance.

---

<div class="post-metadata">

**Author:** ![j-adel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/j-adel/32/207882_2.png) [@j-adel](https://discourse.julialang.org/u/j-adel)\
**Post date:** [April 5, 2024, 8:16pm UTC](https://discourse.julialang.org/t/is-there-a-coalesce-function-for-other-types/60112/14 "2024-04-05T20:16:52Z")

</div>

Just want to point out that `something()` is a thing.
