sets(3)

πŸ“¦
version 29.0.6 Β· 3 versions
, in ubuntu stonking

✨ sets(3) β€” Erlang Module Definition ✨

okay bestie, pull up a chair because we're talking about sets, and honestly? she's iconic. πŸ’…


🌸 NAME 🌸

sets β€” Sets are collections of elements with no duplicate elements. (yes queen, no dupes allowed, we said what we said 🫢)


πŸ’– DESCRIPTION πŸ’–

okay so here's the tea: the data representing a set as used by this module is to be regarded as opaque by other modules. like, don't look at her internals, that's not your business. In abstract terms, the representation is a composite type of existing Erlang terms. See note on data types. Any code assuming knowledge of the format is running on thin ice πŸ§ŠπŸ’€ β€” fr fr, do not do that.

This module provides the same interface as the ordsets module but with an undefined representation. One key difference (and this is the one that gets people, lowkey): this module considers two elements as different if they do not match (=:=), whereas ordsets considers them different if and only if they do not compare equal (==). yes bestie, =:= vs ==, and it MATTERS.

Erlang/OTP 24.0 introduced a new more performant representation for sets which has become the default in Erlang/OTP 28. so if you're on old code, hi, hello. Developers can use the old representation by passing the {version, 1} flag to new/1 and from_list/2. Functions that work on two sets, such as union/2, will work with sets of different versions. In such cases, there is no guarantee about the version of the returned set. (mystery version, she's giving chaos 🌈). Explicit conversion from the old version to the new one can be done with sets:from_list(sets:to_list(Old), [{version,2}]).

✨ Compatibility ✨

The following functions in this module also exist and provide the same functionality in the gb_sets and ordsets modules. That is, by only changing the module name for each call, you can try out different set representations. slay, mix and match, we love options πŸ‘‘

  • add_element/2
  • del_element/2
  • filter/2
  • filtermap/2
  • fold/3
  • from_list/1
  • intersection/1
  • intersection/2
  • is_disjoint/2
  • is_element/2
  • is_empty/1
  • is_equal/2
  • is_set/1
  • is_subset/2
  • map/2
  • new/0
  • size/1
  • subtract/2
  • to_list/1
  • union/1
  • union/2
NOTE: While the three set implementations offer the same functionality with respect to the aforementioned functions, their overall behavior may differ. As mentioned, this module considers elements as different if and only if they do not match (=:=), while both ordsets and gb_sets consider elements as different if and only if they do not compare equal (==).

πŸ¦‹ Examples πŸ¦‹

1> sets:is_element(1.0, sets:from_list([1])).
false
2> ordsets:is_element(1.0, ordsets:from_list([1])).
true
3> gb_sets:is_element(1.0, gb_sets:from_list([1])).
true

look at her go. sets said "1.0 is NOT 1 bestie" and honestly? correct. πŸ’…

πŸ’œ See Also πŸ’œ

gb_sets, ordsets


πŸŽ€ DATA TYPES πŸŽ€

set() :: set(_).
-opaque set(Element)

As returned by new/0. (so if you see one of these in the wild, that's where she came from 🫢)


πŸ‘‘ FUNCTIONS πŸ‘‘

πŸ’– add_element(Element, Set1) -> Set2

when Set1 :: set(Element), Set2 :: set(Element).

Returns a new set formed from Set1 with Element inserted. new set, who dis ✨

πŸ“ Examples πŸ“

1> S0 = sets:new().
2> S1 = sets:add_element(7, S0).
3> sets:to_list(S1).
[7]
4> S2 = sets:add_element(42, S1).
5> lists:sort(sets:to_list(S2)).
[7,42]
6> S2 = sets:add_element(42, S1).
7> lists:sort(sets:to_list(S2)).
[7,42]

notice how adding 42 twice didn't do anything the second time? that's the no-duplicates thing, she's consistent πŸ’…

πŸ’– del_element(Element, Set1) -> Set2

when Set1 :: set(Element), Set2 :: set(Element).

Returns a copy of Set1 with Element removed. bye babe πŸ‘‹ (and if Element wasn't even in there? no drama, she just returns a copy.)

πŸ“ Examples πŸ“

1> S = sets:from_list([a,b]).
2> sets:to_list(sets:del_element(b, S)).
[a]
3> S = sets:del_element(x, S).
4> lists:sort(sets:to_list(S)).
[a,b]

πŸ’– filter(Pred, Set1) -> Set2

when
    Pred :: fun((Element) -> boolean()),
    Set1 :: set(Element),
    Set2 :: set(Element).

Filters elements in Set1 using predicate function Pred. only the ones that pass the vibe check survive πŸ”₯

πŸ“ Examples πŸ“

1> S = sets:from_list([1,2,3,4,5,6,7]).
2> IsEven = fun(N) -> N rem 2 =:= 0 end.
3> Filtered = sets:filter(IsEven, S).
4> lists:sort(sets:to_list(Filtered)).
[2,4,6]

πŸ’– filtermap(Fun, Set1) -> Set2

when
    Fun ::
        fun((Element1) ->
                boolean() | {true, Element2}),
    Set1 :: set(Element1),
    Set2 :: set(Element1 | Element2).

Calls Fun(Elem) for each Elem of Set1 to update or remove elements from Set1. glow-up or goodbye, your choice πŸ’…

Fun/1 must return either a Boolean or a tuple {true, Value}. The function returns the set of elements for which Fun returns a new value, with true being equivalent to {true, Elem}.

sets:filtermap/2 behaves as if it were defined as follows:

filtermap(Fun, Set1) ->
    sets:from_list(lists:filtermap(Fun, sets:to_list(Set1))).

πŸ“ Examples πŸ“

1> S = sets:from_list([2,4,5,6,8,9]).
2> F = fun(X) ->
           case X rem 2 of
               0 -> {true, X div 2};
               1 -> false
           end
        end.
3> Set = sets:filtermap(F, S).
4> lists:sort(sets:to_list(Set)).
[1,2,3,4]

πŸ’– fold(Function, Acc0, Set) -> Acc1

when
    Function :: fun((Element, AccIn) -> AccOut),
    Set :: set(Element),
    Acc0 :: Acc,
    Acc1 :: Acc,
    AccIn :: Acc,
    AccOut :: Acc.

Folds Function over every element in Set and returns the final value of the accumulator.

The evaluation order is undefined. (so don't you dare assume an order, she did not promise you one πŸ™ˆ)

πŸ“ Examples πŸ“

1> S = sets:from_list([1,2,3,4]).
2> Plus = fun erlang:'+'/2.
3> sets:fold(Plus, 0, S).
10

πŸ’– from_list(List) -> Set

when List :: [Element], Set :: set(Element).

Returns a set of the elements in List. glowed up from a humble list πŸ“‹βž‘οΈπŸ‘‘

πŸ“ Examples πŸ“

1> S = sets:from_list([a,b,c]).
2> lists:sort(sets:to_list(S)).
[a,b,c]

πŸ’– from_list(List, [{version, 1..2}]) -> Set

when List :: [Element], Set :: set(Element).

Returns a set of the elements in List of the given version. yes bestie, you can pick your era πŸ•°οΈ

πŸ“ Examples πŸ“

1> S = sets:from_list([a,b,c], [{version, 1}]).
2> lists:sort(sets:to_list(S)).
[a,b,c]

πŸ’– intersection(SetList) -> Set

when
    SetList :: [set(Element), ...],
    Set :: set(Element).

Returns the intersection of the non-empty list of sets. (non-empty!! that ... is doing heavy lifting, respect it πŸ’€)

The intersection of multiple sets is a new set that contains only the elements that are present in all sets. everyone has to agree or she's not coming πŸ’…

πŸ“ Examples πŸ“

1> S0 = sets:from_list([a,b,c,d]).
2> S1 = sets:from_list([d,e,f]).
3> S2 = sets:from_list([q,r]).
4> Sets = [S0, S1, S2].
5> sets:to_list(sets:intersection([S0, S1, S2])).
[]
6> sets:to_list(sets:intersection([S0, S1])).
[d]
7> sets:intersection([]).
** exception error: no function clause matching sets:intersection([])

see line 7? yeah. empty list = exception. she does NOT do empty. noted πŸ“

πŸ’– intersection(Set1, Set2) -> Set3

when
    Set1 :: set(Element),
    Set2 :: set(Element),
    Set3 :: set(Element).

Returns the intersection of Set1 and Set2.

The intersection of two sets is a new set that contains only the elements that are present in both sets.

πŸ“ Examples πŸ“

1> S0 = sets:from_list([a,b,c,d]).
2> S1 = sets:from_list([c,d,e,f]).
3> S2 = sets:from_list([q,r]).
4> Intersection = sets:intersection(S0, S1).
5> lists:sort(sets:to_list(Intersection)).
[c,d]
6> sets:to_list(sets:intersection(S1, S2)).
[]

πŸ’– is_disjoint(Set1, Set2) -> boolean()

when Set1 :: set(Element), Set2 :: set(Element).

Returns true if Set1 and Set2 are disjoint; otherwise, returns false.

Two sets are disjoint if they have no elements in common. zero overlap, zero shared history, they simply do not know each other πŸ™ˆ

This function is equivalent to sets:is_empty(sets:intersection(Set1, Set2)), but faster. faster queen ⚑

πŸ“ Examples πŸ“

1> S0 = sets:from_list([a,b,c,d]).
2> S1 = sets:from_list([d,e,f]).
3> S2 = sets:from_list([q,r]).
4> sets:is_disjoint(S0, S1).
false
5> sets:is_disjoint(S1, S2).
true

πŸ’– is_element(Element, Set) -> boolean()

when Set :: set(Element).

Returns true if Element is an element of Set; otherwise, returns false. is she in the group chat or not 🫢

πŸ“ Examples πŸ“

1> S = sets:from_list([a,b,c]).
2> sets:is_element(42, S).
false
3> sets:is_element(b, S).
true

πŸ’– is_empty(Set) -> boolean()

when Set :: set().

Returns true if Set is an empty set; otherwise, returns false. checking if she has any thoughts in her head πŸ’­

πŸ“ Examples πŸ“

1> sets:is_empty(sets:new()).
true
2> sets:is_empty(sets:from_list([1])).
false

πŸ’– is_equal(Set1, Set2) -> boolean()

when Set1 :: set(), Set2 :: set().

Returns true if Set1 and Set2 are equal, that is, if every element of one set is also a member of the other set; otherwise, returns false. same energy, different vibes internally, doesn't matter πŸ’…

πŸ“ Examples πŸ“

1> Empty = sets:new().
2> S = sets:from_list([a,b]).
3> sets:is_equal(S, S).
true
4> sets:is_equal(S, Empty).
false
5> OldSet = sets:from_list([a,b], [{version,1}]).
6> sets:is_equal(S, OldSet).
true
7> S =:= OldSet.
false

okay lines 6 and 7 are the whole personality of this module: is_equal says TRUE because same elements, but =:= says FALSE because different versions. she contains multitudes πŸ¦‹

πŸ’– is_set(Set) -> boolean()

when Set :: term().

Returns true if Set appears to be a set of elements; otherwise, returns false. appears is the key word here bestie, this is a vibe check not a background check πŸ‘€

NOTE: Note that the test is shallow and will return true for any term that coincides with the possible representations of a set. See also note on data types. Furthermore, since sets are opaque, calling this function on terms that are not sets could result in dialyzer warnings. so like, she warned you πŸ™ˆ

πŸ“ Examples πŸ“

1> sets:is_set(sets:new()).
true
2> sets:is_set(sets:new([{version,1}])).
true
3> sets:is_set(0).
false

πŸ’– is_subset(Set1, Set2) -> boolean()

when Set1 :: set(Element), Set2 :: set(Element).

Returns true when every element of Set1 is also a member of Set2; otherwise, returns false. she fits inside her, cute πŸ₯Ί

πŸ“ Examples πŸ“

1> S0 = sets:from_list([a,b,c,d]).
2> S1 = sets:from_list([c,d]).
3> sets:is_subset(S1, S0).
true
4> sets:is_subset(S0, S1).
false
5> sets:is_subset(S0, S0).
true

okay bestie that's the end of part 1!! πŸŽ€ not me making sets sound like the main character… but she kind of is. more coming ✨

map(Fun, Set1) -> Set2

map(Fun, Set1) -> Set2
                    when
                        Fun :: fun((Element1) -> Element2),
                        Set1 :: set(Element1),
                        Set2 :: set(Element2).

okay bestie, this one is giving transformation energy πŸ’« it takes every element in Set1 and runs it through Fun, then hands you a whole new Set2. no cap, that’s the whole vibe.

Examples

1> S = sets:from_list([1,2,3,4,5,6,7]).
2> F = fun(N) -> N div 2 end.
3> Mapped = sets:map(F, S).
4> lists:sort(sets:to_list(Mapped)).
[0,1,2,3]

new() -> set(none())

new() -> set(none()).

returns a brand new empty set, bestie. zero elements, just immaculate empty vibes ✨.

Examples

1> sets:to_list(sets:new()).
[]

new([{version, 1..2}]) -> set(none())

new([{version, 1..2}]) -> set(none()).

same as new/0 but you get to pick the version, and it still gives you an empty set of that version. version 1..2, no biggie πŸ’….

Examples

1> sets:to_list(sets:new([{version, 1}])).
[]
2> sets:new() =:= sets:new([{version, 2}]).
true

size(Set) -> non_neg_integer() when Set :: set().

size(Set) -> non_neg_integer() when Set :: set().

counts how many elements live in Set and returns a non-negative integer. it’s the headcount of set world πŸ”’.

Examples

1> sets:size(sets:new()).
0
2> sets:size(sets:from_list([4,5,6])).
3

subtract(Set1, Set2) -> Set3

subtract(Set1, Set2) -> Set3
                         when
                             Set1 :: set(Element),
                             Set2 :: set(Element),
                             Set3 :: set(Element).

gives you a new set with everything from Set1 that is not in Set2. it’s the β€œyou can’t sit with us” of set operations πŸ’….

Examples

1> S0 = sets:from_list([a,b,c,d]).
2> S1 = sets:from_list([c,d,e,f]).
3> lists:sort(sets:to_list(sets:subtract(S0, S1))).
[a,b]
4> lists:sort(sets:to_list(sets:subtract(S1, S0))).
[e,f]

to_list(Set) -> List when Set :: set(Element), List :: [Element].

to_list(Set) -> List when Set :: set(Element), List :: [Element].

turns Set into a list. heads up bestie: the order of the returned elements is undefined β€” so don’t assume it’s sorted, fr fr. if you need order, sort it yourself, no cap.

Examples

1> S = sets:from_list([1,2,3]).
2> lists:sort(sets:to_list(S)).
[1,2,3]

union(SetList) -> Set

union(SetList) -> Set
                      when SetList :: [set(Element)], Set :: set(Element).

takes a list of sets and merges them all into one big new set that contains all the elements from all sets, with no duplicates. it’s giving unity, it’s giving community, it’s giving πŸ‘‘.

Examples

1> S0 = sets:from_list([a,b,c,d]).
2> S1 = sets:from_list([d,e,f]).
3> S2 = sets:from_list([q,r]).
4> Sets = [S0, S1, S2].
5> Union = sets:union(Sets).
6> lists:sort(sets:to_list(Union)).
[a,b,c,d,e,f,q,r]

union(Set1, Set2) -> Set3

union(Set1, Set2) -> Set3
                      when
                          Set1 :: set(Element),
                          Set2 :: set(Element),
                          Set3 :: set(Element).

merges Set1 and Set2 into a shiny new set with all their elements, no duplicates allowed. iconic duo behavior 🫢.

Examples

1> S0 = sets:from_list([a,b,c,d]).
2> S1 = sets:from_list([c,d,e,f]).
3> Union = sets:union(S0, S1).
4> lists:sort(sets:to_list(Union)).
[a,b,c,d,e,f]

and that’s a wrap on this half of the page, bestie ✨ this came from Ericsson AB, version stdlib 8.0.4, and it’s the sets(3) manual. date? not in the footer, but it’s timeless anyway. mwah πŸ’‹πŸŽ€

πŸ“¦ where this page comes from