Skip to content

Commit 0c6af15

Browse files
committed
Add ->set and contains?
1 parent e77254a commit 0c6af15

File tree

5 files changed

+140
-3
lines changed

5 files changed

+140
-3
lines changed

docs/api/nfnl/core.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
**Table of contents**
44

5+
- [`->set`](#set)
56
- [`assoc`](#assoc)
67
- [`assoc-in`](#assoc-in)
78
- [`boolean?`](#boolean)
@@ -10,6 +11,7 @@
1011
- [`complement`](#complement)
1112
- [`concat`](#concat)
1213
- [`constantly`](#constantly)
14+
- [`contains?`](#contains)
1315
- [`count`](#count)
1416
- [`dec`](#dec)
1517
- [`distinct`](#distinct)
@@ -58,6 +60,15 @@
5860
- [`update-in`](#update-in)
5961
- [`vals`](#vals)
6062

63+
## `->set`
64+
Function signature:
65+
66+
```
67+
(->set tbl)
68+
```
69+
70+
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.
71+
6172
## `assoc`
6273
Function signature:
6374

@@ -138,6 +149,15 @@ Function signature:
138149

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

152+
## `contains?`
153+
Function signature:
154+
155+
```
156+
(contains? tbl v)
157+
```
158+
159+
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.
160+
141161
## `count`
142162
Function signature:
143163

fnl/nfnl/core.fnl

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,24 @@
454454
(set done? true))))
455455
acc))
456456

457+
(fn ->set [tbl]
458+
"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."
459+
460+
(when tbl
461+
(assert (table? tbl) "Table required as input to ->set.")
462+
(let [result {}]
463+
(each [_n v (ipairs tbl)]
464+
(tset result v true))
465+
result)))
466+
467+
(fn contains? [tbl v]
468+
"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."
469+
(when tbl
470+
(assert (table? tbl) "contains? expects a table")
471+
(if (sequential? tbl)
472+
(or (some #(= $ v) tbl) false)
473+
(= true (. tbl v)))))
474+
457475
{: rand
458476
: nil?
459477
: number?
@@ -508,4 +526,6 @@
508526
: sequential?
509527
: seq
510528
: take-while
511-
: drop-while}
529+
: drop-while
530+
: ->set
531+
: contains?}

fnl/spec/nfnl/core_spec.fnl

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,3 +523,39 @@
523523
(assert.are.same nil (core.drop-while #(> $1 0) nil))
524524
(assert.are.same [] (core.drop-while #(= (. $1 1) :hi) {:hi :world}))
525525
nil))))
526+
527+
(describe
528+
"->set"
529+
(fn []
530+
(it "ignores nil"
531+
(fn []
532+
(assert.is_nil (core.->set nil))
533+
(assert.is_nil (core.->set))
534+
nil))
535+
536+
(it "it turns sequential tables into associative sets"
537+
(fn []
538+
(assert.are.same
539+
{:a true :b true :c true}
540+
(core.->set [:a :b :c]))
541+
nil))))
542+
543+
(describe
544+
"contains?"
545+
(fn []
546+
(it "ignores nil"
547+
(fn []
548+
(assert.is_nil (core.contains? nil :foo))
549+
nil))
550+
551+
(it "works on sequential tables"
552+
(fn []
553+
(assert.is_true (core.contains? [:foo :bar] :foo))
554+
(assert.is_false (core.contains? [:foo :bar] :baz))
555+
nil))
556+
557+
(it "works on associative tables"
558+
(fn []
559+
(assert.is_true (core.contains? (core.->set [:foo :bar]) :foo))
560+
(assert.is_false (core.contains? (core.->set [:foo :bar]) :baz))
561+
nil))))

lua/nfnl/core.lua

Lines changed: 28 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lua/spec/nfnl/core_spec.lua

Lines changed: 35 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)