# Why is there no union!(::Vector,::Vector)?

**URL:** <https://discourse.julialang.org/t/why-is-there-no-union-vector-vector/1366>\
**Category:** Internals & Design\
**Tags:** question\
**Created:** [January 9, 2017, 1:04pm UTC](https://discourse.julialang.org/t/why-is-there-no-union-vector-vector/1366 "2017-01-09T13:04:17Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 9, 2017, 1:04pm UTC](https://discourse.julialang.org/t/why-is-there-no-union-vector-vector/1366/1 "2017-01-09T13:04:17Z")

</div>

I thought I would ask here before opening an issue. Context: I was running a script that was using modules that I did not want to wrap up as a package, so at the beginning I had something like

```julia
push!(LOAD_PATH, expanduser("~/research/some_directory"))

```

During the morning, `LOAD_PATH` filled up nicely with about 100 entries. So I thought I would find the equivalent of

```julia
pushnew!(collection, items...) = push!(collection, setdiff(items, collection)...)

```

in `Base`, but I didn’t. However, I recalled `union!`, which is basically the same. But it has no method for `Vector`s, so I can’t do

```julia
union!(LOAD_PATH, [my_path])

```

at the moment.

The question is: is there a deeper design reason for not having either of these methods, or just that no one got around to writing them?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [January 9, 2017, 1:06pm UTC](https://discourse.julialang.org/t/why-is-there-no-union-vector-vector/1366/2 "2017-01-09T13:06:54Z")

</div>

I think you’re looking for `append!`?

`union!` would seem to imply eliminating duplicates, which is a very different operation from `push!(X, V...)` or `append!(X, V)`, and is an expensive operation for arrays; if you need set-union, you’re better off with `Set` or some other data structure that supports it efficiently.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 9, 2017, 1:27pm UTC](https://discourse.julialang.org/t/why-is-there-no-union-vector-vector/1366/3 "2017-01-09T13:27:35Z")

</div>

Nope, I think I was specifically looking for `pushnew!` above (which many languages with modifiable vectors have, eg [cl:pushnew](http://clhs.lisp.se/Body/m_pshnew.htm)), but was ready to substitute with `union!`. I do realize it is more expensive than `append!`, but sometimes you want to just add **new** elements.

So the question is (before I file an issue): was there a reason for making `union!` work for `Set`s, but not `Vectors`, even though `union` exists for both?

---

<div class="post-metadata">

**Author:** ![nalimilan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nalimilan/32/147_2.png) [@nalimilan](https://discourse.julialang.org/u/nalimilan)\
**Post date:** [January 11, 2017, 9:59am UTC](https://discourse.julialang.org/t/why-is-there-no-union-vector-vector/1366/4 "2017-01-11T09:59:32Z")

</div>

There’s likely no design decision here, just a lack of motivation for implementing this method. I guess it would make sense to add it for completeness.

---

<div class="post-metadata">

**Author:** ![MikeInnes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikeinnes/32/3656_2.png) [@MikeInnes](https://discourse.julialang.org/u/MikeInnes)\
**Post date:** [January 11, 2017, 10:07am UTC](https://discourse.julialang.org/t/why-is-there-no-union-vector-vector/1366/5 "2017-01-11T10:07:57Z")

</div>

Bear in mind that `union!(a, b)` would also have to remove duplicates from `a` in order to return the same result as `union(a, b)` – it’s not quite the same as `pushnew!`. There’s no `unique!(xs)` function exported from Base either, but @nalimilan’s point applies to that too I suppose.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 11, 2017, 10:55am UTC](https://discourse.julialang.org/t/why-is-there-no-union-vector-vector/1366/6 "2017-01-11T10:55:49Z")

</div>

> [@MikeInnes](#):
>
> union!(a, b) would also have to remove duplicates from a in order to return the same result as union(a, b) – it’s not quite the same as pushnew!

This is a good point, thanks! Probably `pushnew!` is more useful than `unique!` then.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [January 11, 2017, 3:33pm UTC](https://discourse.julialang.org/t/why-is-there-no-union-vector-vector/1366/7 "2017-01-11T15:33:33Z")

</div>

This is exactly the functionality of `push!` for a `Set`. If you need this functionality then you should use `Set`, as @stevengj pointed out. This will be much faster than using a `Vector` for `Set`-like functionality.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 11, 2017, 3:48pm UTC](https://discourse.julialang.org/t/why-is-there-no-union-vector-vector/1366/8 "2017-01-11T15:48:14Z")

</div>

Not necessarily a `Set`: there are collections which are ordered, but elements are supposed to be unique (or at least duplicate elements make little sense). `Base.LOAD_PATH` is an example.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [January 11, 2017, 4:47pm UTC](https://discourse.julialang.org/t/why-is-there-no-union-vector-vector/1366/9 "2017-01-11T16:47:49Z")

</div>

Sure, you do sort(collect(S)) at the end.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [January 11, 2017, 4:48pm UTC](https://discourse.julialang.org/t/why-is-there-no-union-vector-vector/1366/10 "2017-01-11T16:48:43Z")

</div>

Ah, you mean temporally ordered, I see. But I think it’s a sufficiently uncommon use case that you can just write your one-liner as you did, without adding anything to Base?

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [January 11, 2017, 4:54pm UTC](https://discourse.julialang.org/t/why-is-there-no-union-vector-vector/1366/11 "2017-01-11T16:54:25Z")

</div>

[http://datastructuresjl.readthedocs.io/en/latest/ordered\_containers.html](http://datastructuresjl.readthedocs.io/en/latest/ordered_containers.html)

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 12, 2017, 10:09am UTC](https://discourse.julialang.org/t/why-is-there-no-union-vector-vector/1366/12 "2017-01-12T10:09:03Z")

</div>

Thanks for all the responses. To summarize, the message I take away from this topic is:

1. `pushnew!` could make sense for `Vector`, and other modifiable collections. I may submit a PR, but I will think more about it. It would simply replace `x ∈ c || push!(c, x)` or similar, so I am not sure it is justified.
2. Naturally, choosing a collection with faster `in` may provide better results for these operators. But they may still make sense for small vectors, etc.
3. `union!` makes less sense for `Vector`, since it would need to remove duplicates from the original, as @MikeInnes pointed out. So I got the answer to my original question. Thanks!

---

<div class="post-metadata">

**Author:** ![nalimilan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nalimilan/32/147_2.png) [@nalimilan](https://discourse.julialang.org/u/nalimilan)\
**Post date:** [January 12, 2017, 12:49pm UTC](https://discourse.julialang.org/t/why-is-there-no-union-vector-vector/1366/13 "2017-01-12T12:49:59Z")

</div>

> [@Tamas\_Papp](#):
>
> union! makes less sense for Vector, since it would need to remove duplicates from the original, as @MikeInnes pointed out. So I got the answer to my original question. Thanks!

Yet it’s not a completely useless method IMHO. I would say methods should be provided for all types for which they are applicable, as long as they make sense.

OTOH, as you say, adding a new `pushnew!` function makes the API bigger without a very clear need.
