Skip to content

Commit f92b9ad

Browse files
committed
feat(iter): add take, drop, slice funcs
1 parent a57584d commit f92b9ad

File tree

2 files changed

+121
-18
lines changed

2 files changed

+121
-18
lines changed

src/iter.fnk

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1+
{max_int} = import './num'
12

2-
# nth ☑ ☐ ☐ ☑
3-
# slice ☐ ☑ ☑ ☐
4-
5-
# partition ☑ ☑ ☐ ☑
6-
# product ☑ ☑ ☐ ☐
7-
# compress ☐ ☑ ☑ ☐
8-
# permutations ☐ ☑ ☑ ☐
3+
# TODO add:
4+
# partition
5+
# product
6+
# compress
7+
# permutations
98

109
repeat = unfold item:
1110
item
@@ -29,6 +28,16 @@ chain = fn ...iterables:
2928
...iterable
3029

3130

31+
insert_at = fn idx, insert_items: fn items:
32+
pipe items:
33+
map item, curr=0:
34+
all = match curr:
35+
idx: chain insert_items, [item]
36+
else: [item]
37+
38+
(...all, curr + 1)
39+
40+
3241
cycle = fn iterable:
3342
pipe [...iterable]:
3443
unfold items:
@@ -51,41 +60,64 @@ sort = fn compare: fn iterable:
5160
[...iterable].sort compare
5261

5362

54-
iterator = fn iterable:
55-
iterable.(Symbol.iterator)()
63+
unique = fn iterable: new Set iterable
5664

5765

58-
unique = fn iterable: new Set iterable
5966

67+
drop = fn num_items: fn items:
68+
pipe items:
69+
map item, idx=0: ([item, idx], idx + 1)
70+
# TODO: should loxia add an accu to filter?
71+
filter [, idx]: idx >= num_items
72+
map [item]: item
6073

61-
next = fn iter:
62-
{done, value} = iter.next()
63-
[value, done]
6474

75+
take = fn num_items: fn items:
76+
iter = items.(Symbol.iterator)()
77+
pipe count 0:
78+
while ctr: ctr < num_items
79+
map _: iter.next()
80+
while {done}: done == false
81+
map {value}: value
6582

66-
next_values = fn iters:
83+
84+
slice = fn start, end=max_int: fn items:
85+
match start:
86+
? + end < 0:
87+
# TODO: use a sliding buffer while iterating over items
88+
[...items].slice start, end
89+
90+
else:
91+
pipe items:
92+
drop start
93+
take end - start
94+
95+
96+
_next_values = fn iters:
6797
pipe iters:
98+
# TODO should we stop getting next item if any are done?
6899
map iter:
69-
[value, done] = next iter
100+
{value, done} = iter.next()
70101
...match done:
71102
true: []
72103
else: [value]
73104

74105

75106
zip = fn ...iterables:
76107
[...iters] = pipe iterables:
77-
map iterable: iterator iterable
108+
map iterable: iterable.(Symbol.iterator)()
78109

79110
{length: min_len} = iters
80111

81112
pipe:
82113
unfold:
83-
[...next_values iters]
114+
[..._next_values iters]
84115

85116
while {length}:
86117
length == min_len
87118

88119

120+
89121
length = fn iterable:
90122
match iterable:
91123
{length: {}}: iterable.length

src/iter.test.fnk

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
{
44
repeat, count, enumerate, zip, cycle, chain, reverse, sort, unique, flatten
5-
length, join, for_each
5+
length, join, for_each, slice, insert_at, take, drop
66
} = import './iter'
77

88
{pad_start} = import './str'
@@ -68,6 +68,15 @@ describe 'iter - transforming funcs', fn:
6868
['a', 'b', 'c', 1, 2, 3]
6969

7070

71+
it 'inserts items into iterable', fn:
72+
expect
73+
pipe '123456':
74+
insert_at 3, 'abc'
75+
join ''
76+
to_equal
77+
'123abc456'
78+
79+
7180
it 'creates unique set of items', fn:
7281
expect
7382
pipe [1, 2, 2, 3]:
@@ -106,6 +115,68 @@ describe 'iter - transforming funcs', fn:
106115
['1', '2', '11', '222']
107116

108117

118+
describe 'slice', fn:
119+
it 'advances ignores n elements', fn:
120+
expect
121+
pipe '1234567890':
122+
drop 5
123+
join ''
124+
to_equal '67890'
125+
126+
127+
it 'filters n elements', fn:
128+
expect
129+
pipe '1234567890':
130+
take 5
131+
join ''
132+
to_equal '12345'
133+
134+
135+
it 'takes 0 length slice', fn:
136+
expect
137+
pipe count 0:
138+
slice 1, 1
139+
[...?]
140+
to_equal
141+
[]
142+
143+
144+
it 'takes regular slice', fn:
145+
expect
146+
pipe count 0:
147+
slice 0, 3
148+
[...?]
149+
to_equal
150+
[0, 1, 2]
151+
152+
153+
it 'takes slice from start to end of iterable', fn:
154+
expect
155+
pipe '0123456789':
156+
slice 5
157+
[...?]
158+
to_equal
159+
[...'56789']
160+
161+
162+
it 'takes end-offset slice', fn:
163+
expect
164+
pipe '0123456789':
165+
slice 0, -5
166+
[...?]
167+
to_equal
168+
[...'01234']
169+
170+
expect
171+
pipe '0123456789':
172+
# TODO remove parens
173+
slice (-5, -1)
174+
[...?]
175+
to_equal
176+
[...'5678']
177+
178+
179+
109180
describe 'folding funcs', fn:
110181
it 'gets length', fn:
111182
expect

0 commit comments

Comments
 (0)