Skip to content

Commit

Permalink
Add ->set and contains?
Browse files Browse the repository at this point in the history
  • Loading branch information
Olical committed Feb 19, 2025
1 parent e77254a commit 0c6af15
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 3 deletions.
20 changes: 20 additions & 0 deletions docs/api/nfnl/core.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

**Table of contents**

- [`->set`](#set)
- [`assoc`](#assoc)
- [`assoc-in`](#assoc-in)
- [`boolean?`](#boolean)
Expand All @@ -10,6 +11,7 @@
- [`complement`](#complement)
- [`concat`](#concat)
- [`constantly`](#constantly)
- [`contains?`](#contains)
- [`count`](#count)
- [`dec`](#dec)
- [`distinct`](#distinct)
Expand Down Expand Up @@ -58,6 +60,15 @@
- [`update-in`](#update-in)
- [`vals`](#vals)

## `->set`
Function signature:

```
(->set tbl)
```

Converts a table `tbl` to a 'set' - which means [:a :b] becomes {:a true :b true}. You can then use contains? to check membership, or just (. my-set :foo) - if that returns true, it's in your set.

## `assoc`
Function signature:

Expand Down Expand Up @@ -138,6 +149,15 @@ Function signature:

Returns a function that takes any number of arguments and returns `v`.

## `contains?`
Function signature:

```
(contains? tbl v)
```

Does the table `tbl` contain the value `v`? If given an associative table it'll check for membership of the key, if given a sequential table it will scan for the value. Associative is essentially O(1), sequential is O(n). You can use `->set` if you need to perform many lookups, it will turn [:a :b] into {:a true :b true} which is O(1) to check.

## `count`
Function signature:

Expand Down
22 changes: 21 additions & 1 deletion fnl/nfnl/core.fnl
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,24 @@
(set done? true))))
acc))

(fn ->set [tbl]
"Converts a table `tbl` to a 'set' - which means [:a :b] becomes {:a true :b true}. You can then use contains? to check membership, or just (. my-set :foo) - if that returns true, it's in your set."

(when tbl
(assert (table? tbl) "Table required as input to ->set.")
(let [result {}]
(each [_n v (ipairs tbl)]
(tset result v true))
result)))

(fn contains? [tbl v]
"Does the table `tbl` contain the value `v`? If given an associative table it'll check for membership of the key, if given a sequential table it will scan for the value. Associative is essentially O(1), sequential is O(n). You can use `->set` if you need to perform many lookups, it will turn [:a :b] into {:a true :b true} which is O(1) to check."
(when tbl
(assert (table? tbl) "contains? expects a table")
(if (sequential? tbl)
(or (some #(= $ v) tbl) false)
(= true (. tbl v)))))

{: rand
: nil?
: number?
Expand Down Expand Up @@ -508,4 +526,6 @@
: sequential?
: seq
: take-while
: drop-while}
: drop-while
: ->set
: contains?}
36 changes: 36 additions & 0 deletions fnl/spec/nfnl/core_spec.fnl
Original file line number Diff line number Diff line change
Expand Up @@ -523,3 +523,39 @@
(assert.are.same nil (core.drop-while #(> $1 0) nil))
(assert.are.same [] (core.drop-while #(= (. $1 1) :hi) {:hi :world}))
nil))))

(describe
"->set"
(fn []
(it "ignores nil"
(fn []
(assert.is_nil (core.->set nil))
(assert.is_nil (core.->set))
nil))

(it "it turns sequential tables into associative sets"
(fn []
(assert.are.same
{:a true :b true :c true}
(core.->set [:a :b :c]))
nil))))

(describe
"contains?"
(fn []
(it "ignores nil"
(fn []
(assert.is_nil (core.contains? nil :foo))
nil))

(it "works on sequential tables"
(fn []
(assert.is_true (core.contains? [:foo :bar] :foo))
(assert.is_false (core.contains? [:foo :bar] :baz))
nil))

(it "works on associative tables"
(fn []
(assert.is_true (core.contains? (core.->set [:foo :bar]) :foo))
(assert.is_false (core.contains? (core.->set [:foo :bar]) :baz))
nil))))
29 changes: 28 additions & 1 deletion lua/nfnl/core.lua

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 35 additions & 1 deletion lua/spec/nfnl/core_spec.lua

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 0c6af15

Please sign in to comment.