# How to convert Vector{Any} to a narrower type?

**URL:** <https://discourse.julialang.org/t/how-to-convert-vector-any-to-a-narrower-type/60376>\
**Category:** General Usage\
**Created:** [May 1, 2021, 12:23pm UTC](https://discourse.julialang.org/t/how-to-convert-vector-any-to-a-narrower-type/60376 "2021-05-01T12:23:48Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![greatpet](https://avatars.discourse-cdn.com/v4/letter/g/e495f1/32.png) [@greatpet](https://discourse.julialang.org/u/greatpet)\
**Post date:** [May 1, 2021, 12:23pm UTC](https://discourse.julialang.org/t/how-to-convert-vector-any-to-a-narrower-type/60376/1 "2021-05-01T12:23:49Z")

</div>

Consider the following Julia code

```
julia> a = Any[1, 2, 3.0]
3-element Vector{Any}:
 1
 2
 3.0

julia> map(x->x, a)
3-element Vector{Real}:
 1
 2
 3.0

```

Here I abused `map` to convert an array of `Any` to the narrowest type `Real` that all elements belong to. Is there a less hacky way to do this, while retaining the automatic detection of actual types inside the array?

---

<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:** [May 1, 2021, 12:29pm UTC](https://discourse.julialang.org/t/how-to-convert-vector-any-to-a-narrower-type/60376/2 "2021-05-01T12:29:57Z")

</div>

You can broadcast identity.

> [@Is there a coalesce function for other types?](https://discourse.julialang.org/t/is-there-a-coalesce-function-for-other-types/60112):
>
> 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. 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: clean(a,junk,target) = identity.(replace(a, (junk .=\> target)...)) clean(a,["",missing,NaN],0)

---

<div class="post-metadata">

**Author:** ![cscherrer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cscherrer/32/7631_2.png) [@cscherrer](https://discourse.julialang.org/u/cscherrer)\
**Post date:** [May 25, 2022, 5:36pm UTC](https://discourse.julialang.org/t/how-to-convert-vector-any-to-a-narrower-type/60376/3 "2022-05-25T17:36:03Z")

</div>

I just came across this and thought it’s worth benchmarking. ~~Looks like `map` is better suited for this~~ :

I had thought `map` might be the best approach, but I looked at the code it produces:

```julia
julia> @code_typed map(identity, a)
CodeInfo(
1 ─ %1 = %new(Generator{Vector{Any}, typeof(identity)}, identity, A)::Generator{Vector{Any}, typeof(identity)}
│ %2 = invoke Base._collect(A::Vector{Any}, %1::Generator{Vector{Any}, typeof(identity)}, $(QuoteNode(EltypeUnknown()))::EltypeUnknown, $(QuoteNode(HasShape{1}()))::HasShape{1})::Vector
└── return %2
)=>Vector

```

Ok, so first it makes a generator, then collects it. So let’s try that:

```julia
julia> a = Any[1, 2, 3.0]
3-element Vector{Any}:
 1
 2
 3.0

julia> @btime identity.(a)
  1.815 μs (18 allocations: 720 bytes)
3-element Vector{Real}:
 1
 2
 3.0

julia> @btime map(identity, a)
  588.475 ns (8 allocations: 256 bytes)
3-element Vector{Real}:
 1
 2
 3.0

julia> @btime collect((x for x in $a))
  258.529 ns (6 allocations: 224 bytes)
3-element Vector{Real}:
 1
 2
 3.0

```

I’m not sure why this is so much faster. But it seems to work for arrays too, no problem:

```julia
julia> b = [a randn(3)]
3×2 Matrix{Any}:
 1 0.105208
 2 -1.05589
 3.0 0.310332

julia> collect((x for x in b))
3×2 Matrix{Real}:
 1 0.105208
 2 -1.05589
 3.0 0.310332

```

---

<div class="post-metadata">

**Author:** ![Lincoln\_Hannah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lincoln_hannah/32/19198_2.png) [@Lincoln\_Hannah](https://discourse.julialang.org/u/Lincoln_Hannah)\
**Post date:** [May 25, 2023, 1:14am UTC](https://discourse.julialang.org/t/how-to-convert-vector-any-to-a-narrower-type/60376/5 "2023-05-25T01:14:06Z")

</div>

It would be nice if Base included something like

```julia
identity(x::Vector) = identity.(x)

```

My usage:  
Using `SplitApplyCombine.group` to split vector of deals into a dictionary of vectors of deal subtypes. Then apply `Value` to each vector.

```julia
@> group( typeof, deals ) Value.()

```

But the vectors produced by `group` are all of the parent {deal} type. To apply the right Value method I need to convert each Vector{deal} to a Vector{deal-subtype} using:

```julia
Value( x::Vector{deal} ) = Value( identity.(x))

```

It would be nice to instead write:

```julia
Value(::Vector{deal}) = Value ∘ identity 

```

---

<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:** [May 25, 2023, 6:51am UTC](https://discourse.julialang.org/t/how-to-convert-vector-any-to-a-narrower-type/60376/6 "2023-05-25T06:51:27Z")

</div>

It’s pretty simple to add `identity.(...)` explicitly before calling `Value(...)`, no need to define new methods:

```julia
using DataPipes # not sure which piping package you used, here showing example with DataPipes

@p group(typeof, deals) |> map(Value(identity.(_)))
# or
@p group(typeof, deals) .|> Value.(identity.(__))

```

Being explicit helps understanding what the code actually does.

> [@Lincoln\_Hannah](#):
>
> It would be nice to instead write:
> 
> ```julia
> Value(::Vector{deal}) = Value ∘ identity 
> 
> ```

That doesn’t use the argument at all, and returns the function instead of the modified vector.

> [@Lincoln\_Hannah](#):
>
> It would be nice if Base included something like
> 
> ```julia
> identity(x::Vector) = identity.(x)
> 
> ```

`identity` is definitely the wrong function to overload: it’s specifically to always return its argument unmodified.  
And defining a new function, making everyone aware of it – sounds way too much simply to avoid writing the dot `.`.

---

<div class="post-metadata">

**Author:** ![Lincoln\_Hannah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lincoln_hannah/32/19198_2.png) [@Lincoln\_Hannah](https://discourse.julialang.org/u/Lincoln_Hannah)\
**Post date:** [June 30, 2023, 4:55am UTC](https://discourse.julialang.org/t/how-to-convert-vector-any-to-a-narrower-type/60376/7 "2023-06-30T04:55:28Z")

</div>

```julia
f(::Pair{Symbol,Int64}) = "pair_Symbol_Int64"
f(::Pair{Symbol,String}) = "pair_Symbol_String"
f(::Pair) = "pair"

[Pair(:x,"a"), Pair(:y,2.3)][1] |> f

```

returns `pair`. I’d like to return `pair_Symbol_String`

Is this possible ?

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [June 30, 2023, 5:28am UTC](https://discourse.julialang.org/t/how-to-convert-vector-any-to-a-narrower-type/60376/8 "2023-06-30T05:28:52Z")

</div>

```julia
julia> Any[Pair(:x,"a"), Pair(:y,2.3)][1] |> f
"pair_Symbol_String"

```

---

<div class="post-metadata">

**Author:** ![Lincoln\_Hannah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lincoln_hannah/32/19198_2.png) [@Lincoln\_Hannah](https://discourse.julialang.org/u/Lincoln_Hannah)\
**Post date:** [June 30, 2023, 5:54am UTC](https://discourse.julialang.org/t/how-to-convert-vector-any-to-a-narrower-type/60376/10 "2023-06-30T05:54:17Z")

</div>

```julia
x = [Pair(:a,1),Pair(:b,"s")]  
y = Any[Pair(:a,1),Pair(:b,"s")]

f.( y ) #works
f.( convert(Vector{Any}, x) ) #doesn't work

```

how can I do it with applying a function to `x` ?

`Any[x...]` isn’t the same as `Any[Pair(:a,1),Pair(:b,"s")] `

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [June 30, 2023, 6:13am UTC](https://discourse.julialang.org/t/how-to-convert-vector-any-to-a-narrower-type/60376/11 "2023-06-30T06:13:19Z")

</div>

You need to repackage them into better types, e.g.

```julia
julia> f.(map(p -> Pair(p...), x))
2-element Vector{String}:
 "pair_Symbol_Int64"
 "pair_Symbol_String"

```

---

<div class="post-metadata">

**Author:** ![Lincoln\_Hannah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lincoln_hannah/32/19198_2.png) [@Lincoln\_Hannah](https://discourse.julialang.org/u/Lincoln_Hannah)\
**Post date:** [June 30, 2023, 6:13am UTC](https://discourse.julialang.org/t/how-to-convert-vector-any-to-a-narrower-type/60376/12 "2023-06-30T06:13:56Z")

</div>

thanks

---

<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:** [June 30, 2023, 8:19am UTC](https://discourse.julialang.org/t/how-to-convert-vector-any-to-a-narrower-type/60376/13 "2023-06-30T08:19:25Z")

</div>

This issue is specific to `Pair` and a few other promotable types. IMO, it is pretty unusual that simply putting an object into array changes it:

```julia
julia> p1 = Pair(:x,"a")
julia> p2 = Pair(:y,2.3)
julia> [p1, p2]

julia> [p1, p2][1] === p1
false

```

But that’s how it is defined…

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [June 30, 2023, 11:31am UTC](https://discourse.julialang.org/t/how-to-convert-vector-any-to-a-narrower-type/60376/14 "2023-06-30T11:31:05Z")

</div>

I mean you can prevent it, but you need to define all the `Pair`s with a compatible type before.

```julia
julia> p1 = Pair{Symbol,Any}(:x,"a")
Pair{Symbol, Any}(:x, "a")

julia> p2 = Pair{Symbol,Any}(:y,2.3)
Pair{Symbol, Any}(:y, 2.3)

julia> [p1, p2][1] === p1
true

```
