# Weird behaviour of "setdiff"

**URL:** https://discourse.julialang.org/t/weird-behaviour-of-setdiff/88110
**Category:** General Usage
**Created:** [October 2, 2022, 6:56am UTC](https://discourse.julialang.org/t/weird-behaviour-of-setdiff/88110 "2022-10-02T06:56:06Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![lionisxn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lionisxn/32/37989_2.png) [@lionisxn](https://discourse.julialang.org/u/lionisxn)
#### Post date: [October 2, 2022, 6:56am UTC](https://discourse.julialang.org/t/weird-behaviour-of-setdiff/88110/1 "2022-10-02T06:56:06Z")

</div>

I just found that the weird behaviour of “setdiff” in the 1.8.2, as can be seen in the following figure:  
 ![微信截图_20221002144818](https://global.discourse-cdn.com/julialang/original/3X/2/4/24b69d05f3e3c4130c22a35284609e0e7d843888.png)

I think the “correct” result should be ‘[’, ‘1’, '1, ‘]’. Such a minor change leads to unexpected behaviour of all my old codes.

---

<div class="post-metadata">

### Author: ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)
#### Post date: [October 2, 2022, 7:11am UTC](https://discourse.julialang.org/t/weird-behaviour-of-setdiff/88110/2 "2022-10-02T07:11:21Z")

</div>

It returns distinct values, though it could be spelled out more in the docstring.

> Construct the set of elements in s but not in any of the iterables in itrs. Maintain order with arrays.

```julia
julia> setdiff("aaa","b")
1-element Vector{Char}:
 'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)

```

You can use filter instead

```julia
julia> filter(≠('_'), "_[11]")
"[11]"

```

---

<div class="post-metadata">

### Author: ![suavesito](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/suavesito/32/34386_2.png) [@suavesito](https://discourse.julialang.org/u/suavesito)
#### Post date: [October 2, 2022, 7:13am UTC](https://discourse.julialang.org/t/weird-behaviour-of-setdiff/88110/3 "2022-10-02T07:13:40Z")

</div>

The behaviour of `setdiff` seems correct to me. As per the documentation

> `setdiff(s, itrs...)`  
> Construct the set of elements in `s` but not in any of the iterables in `itrs`. Maintain order with arrays.

If you notice, a `String` is an iterable of `Char`’s[1], so it will return the set of chars present in the first string, but not in the second. A set by definition (mathematics) **does not repeat values**. For this, the return value is correct.

(1)

```julia
julia> for c in "hello"
           println(c)
       end
h
e
l
l
o

```

---

<div class="post-metadata">

### Author: ![suavesito](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/suavesito/32/34386_2.png) [@suavesito](https://discourse.julialang.org/u/suavesito)
#### Post date: [October 2, 2022, 7:16am UTC](https://discourse.julialang.org/t/weird-behaviour-of-setdiff/88110/4 "2022-10-02T07:16:59Z")

</div>

> [@jar1](#):
>
> though it could be spelled out more in the docstring.

I guess this is not the case because a set is well-defined in Computer Science and Mathematics as a collection of unique elements (skipping a lot of details, really). But if you think the docs could be improved, you can feel free to fill an issue in GitHub or make a Pull Request. 🙂

---

<div class="post-metadata">

### Author: ![lionisxn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lionisxn/32/37989_2.png) [@lionisxn](https://discourse.julialang.org/u/lionisxn)
#### Post date: [October 2, 2022, 7:19am UTC](https://discourse.julialang.org/t/weird-behaviour-of-setdiff/88110/5 "2022-10-02T07:19:31Z")

</div>

All right! But I have to reload it in my package, and redefine my desired behaviour using filter!

---

<div class="post-metadata">

### Author: ![lionisxn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lionisxn/32/37989_2.png) [@lionisxn](https://discourse.julialang.org/u/lionisxn)
#### Post date: [October 2, 2022, 7:24am UTC](https://discourse.julialang.org/t/weird-behaviour-of-setdiff/88110/6 "2022-10-02T07:24:15Z")

</div>

It seems that “setdiff” is not oriented to string manipulation, it makes sense in Mathematics.

---

<div class="post-metadata">

### Author: ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)
#### Post date: [October 2, 2022, 2:50pm UTC](https://discourse.julialang.org/t/weird-behaviour-of-setdiff/88110/7 "2022-10-02T14:50:08Z")

</div>

> [@lionisxn](#):
>
> redefine my desired behaviour using filter!

If you just need to remove the character from the string, you can use `replace` instead. It returns a string. If you do need it to be a `Vector{Char}`, you can `collect` that too.

```julia
julia> s = "_[11]"
"_[11]"

julia> replace(s, "_" => "")
"[11]"

julia> collect(replace(s, "_" => ""))
4-element Vector{Char}:
 '[': ASCII/Unicode U+005B (category Ps: Punctuation, open)
 '1': ASCII/Unicode U+0031 (category Nd: Number, decimal digit)
 '1': ASCII/Unicode U+0031 (category Nd: Number, decimal digit)
 ']': ASCII/Unicode U+005D (category Pe: Punctuation, close)

```

---

<div class="post-metadata">

### Author: ![lionisxn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lionisxn/32/37989_2.png) [@lionisxn](https://discourse.julialang.org/u/lionisxn)
#### Post date: [October 2, 2022, 4:14pm UTC](https://discourse.julialang.org/t/weird-behaviour-of-setdiff/88110/8 "2022-10-02T16:14:31Z")

</div>

Yes, it is also a good choice!

---

<div class="post-metadata">

### Author: ![matthias314](https://avatars.discourse-cdn.com/v4/letter/m/a88e4f/32.png) [@matthias314](https://discourse.julialang.org/u/matthias314)
#### Post date: [October 8, 2022, 8:49pm UTC](https://discourse.julialang.org/t/weird-behaviour-of-setdiff/88110/9 "2022-10-08T20:49:48Z")

</div>

There is another aspect here that I find weird. As mentioned already, the documentation says that `setdiff` returns a set. In this example, however, it returns a `Vector{Char}`, and that is not a subtype of `Set`.

---

<div class="post-metadata">

### Author: ![suavesito](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/suavesito/32/34386_2.png) [@suavesito](https://discourse.julialang.org/u/suavesito)
#### Post date: [October 8, 2022, 9:03pm UTC](https://discourse.julialang.org/t/weird-behaviour-of-setdiff/88110/10 "2022-10-08T21:03:59Z")

</div>

It returns a _set_ not a `Set`, that means that it returns a set in the mathematical meaning of the word. That the set (collection of unique value) returned is not a `Set` (data structure) is not really relevant. I guess it would be more clear if the documentation explicitly said something about it, maybe along the lines of

> `setdiff(s, itrs...)`  
> Construct an `Array` containing the set of elements in `s` but not in any of the iterables in `itrs`. Maintain order with arrays.

---

<div class="post-metadata">

### Author: ![matthias314](https://avatars.discourse-cdn.com/v4/letter/m/a88e4f/32.png) [@matthias314](https://discourse.julialang.org/u/matthias314)
#### Post date: [October 8, 2022, 9:14pm UTC](https://discourse.julialang.org/t/weird-behaviour-of-setdiff/88110/11 "2022-10-08T21:14:35Z")

</div>

I see. I agree that it would be a good idea to state explicitly in the documentation that `setdiff` does not only work with `Set`s. The return type seems to depend on the first argument. (It’s not always an `Array`.) I’ve just seen that for `union` this is already documented.
