# Efficient way of creating a vector of length L with unique elements

**URL:** <https://discourse.julialang.org/t/efficient-way-of-creating-a-vector-of-length-l-with-unique-elements/98388>\
**Category:** Performance\
**Tags:** vector, random\
**Created:** [May 5, 2023, 3:38pm UTC](https://discourse.julialang.org/t/efficient-way-of-creating-a-vector-of-length-l-with-unique-elements/98388 "2023-05-05T15:38:28Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![dm17017](https://avatars.discourse-cdn.com/v4/letter/d/c37758/32.png) [@dm17017](https://discourse.julialang.org/u/dm17017)\
**Post date:** [May 5, 2023, 3:38pm UTC](https://discourse.julialang.org/t/efficient-way-of-creating-a-vector-of-length-l-with-unique-elements/98388/1 "2023-05-05T15:38:28Z")

</div>

Hi,

I am looking to fill a vector of a desired length up with randomly chosen, unique elements. Currently I have the code below which has the desired effect however, I suspect I can speed it up. If anyone has any ideas it would be appreciated

```julia
function randomly_filling_vector(R1, R2, L)
    
out = [Vector{Int64}(undef,3) for _ in 1:L]
    condit = false
    while condit == false  
        for i ∈ eachindex(out)
            out[i] = [rand(DiscreteUniform(1, R1)), rand(DiscreteUniform(2, R2-1)), rand(DiscreteUniform(1, 6))]
        end
        unique = unique!(out)
        if length(unique) == L
            condit = true
            return out
        end
    end
end

```

---

<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:** [May 5, 2023, 4:33pm UTC](https://discourse.julialang.org/t/efficient-way-of-creating-a-vector-of-length-l-with-unique-elements/98388/2 "2023-05-05T16:33:42Z")

</div>

> [@dm17017](#):
>
> I am looking to fill a vector of a desired length up with randomly chosen, unique elements.

This is called “random sampling without replacement” and is implemented e.g. by [`StatsBase.sample`](https://juliastats.org/StatsBase.jl/stable/sampling/#StatsBase.sample).

See also [Sampling from a list of integers without repetition](https://discourse.julialang.org/t/sampling-from-a-list-of-integers-without-repetition/41395) and [Sampling without replacement](https://discourse.julialang.org/t/sampling-without-replacement/1073).

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [May 5, 2023, 4:42pm UTC](https://discourse.julialang.org/t/efficient-way-of-creating-a-vector-of-length-l-with-unique-elements/98388/3 "2023-05-05T16:42:08Z")

</div>

There is a problem with the algorithm you implemented. The line

> [@dm17017](#):
>
> ```julia
> unique = unique!(out)
> 
> ```

uses `unique!` which mutates the `out` array. This array will get shortened when there are repeating elements in `out` and subsequently will never be lengthened back, as `eachindex(out)` in the `for` earlier will loop over shortened array. Thus the function will enter an infinite loop.

So, first, fixed OP code:

```julia
function randomly_filling_vector(R1, R2, L)
    out = [Vector{Int64}(undef,3) for _ in 1:L]
    condit = false
    while condit == false  
        for i ∈ eachindex(out)
            out[i] = [rand(DiscreteUniform(1, R1)), rand(DiscreteUniform(2, R2-1)), rand(DiscreteUniform(1, 6))]
        end
        uniq = unique(out)
        if length(uniq) == L
            condit = true
            return out
        end
    end
end

```

But, as stevengj mentioned, this is work for `sample` from `Random` package. The following is an efficient way to implement this:

```julia
function randomly_filling_vector2(R1, R2, L)
    S = R1*(R2-2)*6
    map(sample(1:S, L; replace=false)) do s
        d, m = divrem(s, 6)
        c3 = m+1
        d, m = divrem(d, R2-2)
        c2 = m+2
        c1 = d+1
        [c1, c2, c3]
    end
end

```

---

<div class="post-metadata">

**Author:** ![dm17017](https://avatars.discourse-cdn.com/v4/letter/d/c37758/32.png) [@dm17017](https://discourse.julialang.org/u/dm17017)\
**Post date:** [May 5, 2023, 4:45pm UTC](https://discourse.julialang.org/t/efficient-way-of-creating-a-vector-of-length-l-with-unique-elements/98388/4 "2023-05-05T16:45:31Z")

</div>

> [@Dan](#):
>
> ```julia
> function randomly_filling_vector2(R1, R2, L)
> S = R1*(R2-2)*6
> map(sample(1:S, L; replace=false)) do s
> d, m = divrem(s, 6)
> c3 = m+1
> d, m = divrem(d, R2-2)
> c2 = m+2
> c1 = d+1
> [c1, c2, c3]
> end
> end
> 
> ```

Amazing. Thankyou for your help
