Module: Fr::SZipper::Enumerable

Included in:
AbstractCursor
Defined in:
lib/fr/szipper/enumerable.rb

Instance Method Summary collapse

Instance Method Details

#all?Boolean

Returns:

  • (Boolean)


18
19
20
21
22
# File 'lib/fr/szipper/enumerable.rb', line 18

def all?
  catch(:done) do
    each{|c| throw(:done, false) if !yield(c.node) }; true
  end
end

#any?Boolean Also known as: one?

Returns:

  • (Boolean)


24
25
26
27
28
# File 'lib/fr/szipper/enumerable.rb', line 24

def any?
  catch(:done) do
    each{|c| throw(:done, true) if yield(c.node) }; false
  end
end

#chunkObject



30
31
32
# File 'lib/fr/szipper/enumerable.rb', line 30

def chunk
  # todo: defined?
end

#collectObject Also known as: map



34
35
36
37
38
39
40
41
42
# File 'lib/fr/szipper/enumerable.rb', line 34

def collect
  unless tail?
    current = yield(node)
    next_   = Fr.thunk { self.next.collect{|n| yield(n) }.node }
    replace(current.copy(next: next_))
  else
    update(yield(node))
  end
end

#collect_concatObject



44
45
46
# File 'lib/fr/szipper/enumerable.rb', line 44

def collect_concat
  # todo: defined?
end

#countObject



48
49
50
# File 'lib/fr/szipper/enumerable.rb', line 48

def count
  foldl(0){|count, c| yield(c.node) ? count + 1 : count }
end

#cycleObject



52
53
54
# File 'lib/fr/szipper/enumerable.rb', line 52

def cycle
  # todo: defined?
end

#detect(default = nil) ⇒ Object Also known as: find



56
57
58
59
60
# File 'lib/fr/szipper/enumerable.rb', line 56

def detect(default = nil)
  catch(:done) do
    each{|c| throw(:done, c) if yield(c.node) }; default
  end
end

#drop(n) ⇒ Object



62
63
64
65
66
67
# File 'lib/fr/szipper/enumerable.rb', line 62

def drop(n)
  # Seek n nodes forward
  nth = n.times.inject(self.next(true)){|c,_| c.next(true) }
  mth = node.copy(next: nth.prev.node.next)
  replace(mth)
end

#drop_whileObject



69
70
71
# File 'lib/fr/szipper/enumerable.rb', line 69

def drop_while
  # todo
end

#each {|cursor| ... } ⇒ Object

Yields:

  • (cursor)


6
7
8
9
10
11
12
13
14
15
16
# File 'lib/fr/szipper/enumerable.rb', line 6

def each
  cursor = self
  yield(cursor)

  until cursor.tail?
    cursor = cursor.next
    yield(cursor)
  end

  self
end

#entriesObject Also known as: to_a



73
74
75
# File 'lib/fr/szipper/enumerable.rb', line 73

def entries
  foldl([]){|entries, c| entries << c.node }
end

#filterObject Also known as: find_all, select



79
80
81
82
83
84
85
86
# File 'lib/fr/szipper/enumerable.rb', line 79

def filter
  node = filter_{|n| yield(n) }
  unless node.nil?
    replace(node)
  else
    prev(true).truncate
  end
end

#filter_Object



89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/fr/szipper/enumerable.rb', line 89

def filter_
  unless tail?
    Fr.thunk do
      if yield(node)
        node.copy(next: self.next.filter_{|n| yield(n) })
      else
        self.next.filter_{|n| yield(n) }
      end
    end
  else
    yield(node) ?
      node : nil
  end
end

#first(n = 1) ⇒ Object

alias_method :first, :head



125
126
127
128
129
130
131
# File 'lib/fr/szipper/enumerable.rb', line 125

def first(n = 1)
  if n == 1
    head
  else
    # todo: defined?
  end
end

#flat_mapObject



133
134
135
# File 'lib/fr/szipper/enumerable.rb', line 133

def flat_map
  # todo
end

#foldl(svalue) ⇒ Object Also known as: inject



149
150
151
152
153
154
155
156
157
# File 'lib/fr/szipper/enumerable.rb', line 149

def foldl(svalue)
  cursor = self
  svalue = yield(svalue, cursor)
  until cursor.tail?
    cursor = cursor.next
    svalue = yield(svalue, cursor)
  end
  svalue
end

#grep(pattern) ⇒ Object



137
138
139
# File 'lib/fr/szipper/enumerable.rb', line 137

def grep(pattern)
  filter{|node| pattern === node }
end

#group_byObject



141
142
143
# File 'lib/fr/szipper/enumerable.rb', line 141

def group_by
  # todo: defined?
end

#include?(needle) ⇒ Boolean

Returns:

  • (Boolean)


145
146
147
# File 'lib/fr/szipper/enumerable.rb', line 145

def include?(needle)
  any?{|node| node == needle }
end

#index(default = nil) ⇒ Object Also known as: find_index



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/fr/szipper/enumerable.rb', line 106

def index(default = nil)
  position_ = position

  catch(:done) do
    each do |c|
      if yield(c.node)
        throw(:done, position_)
      else
        position_ += 1
      end
    end

    default
  end
end

#maxObject



163
164
165
# File 'lib/fr/szipper/enumerable.rb', line 163

def max
  reduce{|a,b| a.node < b.node ? b : a }
end

#max_byObject



167
168
169
# File 'lib/fr/szipper/enumerable.rb', line 167

def max_by
  reduce{|a,b| yield(a.node) < yield(b.node) ? b : a }
end

#minObject



171
172
173
# File 'lib/fr/szipper/enumerable.rb', line 171

def min
  reduce{|a,b| a.node > b.node ? b : a }
end

#min_byObject



175
176
177
# File 'lib/fr/szipper/enumerable.rb', line 175

def min_by
  reduce{|a,b| yield(a.node) > yield(b.node) ? b : a }
end

#minmaxObject



179
180
181
182
183
184
# File 'lib/fr/szipper/enumerable.rb', line 179

def minmax
  foldl([self, self]) do |(min,max), c|
    [min.node > c.node ? c : min,
     max.node < c.node ? c : max]
  end
end

#minmax_byObject



186
187
188
189
190
191
# File 'lib/fr/szipper/enumerable.rb', line 186

def minmax_by
  foldl([self, self]) do |(min,max), c|
    [yield(min.node) > yield(c.node) ? c : min,
     yield(max.node) < yield(c.node) ? c : max]
  end
end

#none?Boolean

Returns:

  • (Boolean)


193
194
195
196
197
# File 'lib/fr/szipper/enumerable.rb', line 193

def none?
  catch(:done) do
    each{|c| throw(:done, false) if yield(c.node) }; true
  end
end

#partitionObject



201
202
203
# File 'lib/fr/szipper/enumerable.rb', line 201

def partition
  # todo
end

#reduce(op = nil) ⇒ Object



205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/fr/szipper/enumerable.rb', line 205

def reduce(op = nil)
  # [].reduce(op)       #=> nil
  # [a].reduce(op)      #=> a
  # [a,b].reduce(op)    #=> a op b
  # [a,b,c].reduce(op)  #=> a op b op c

  svalue = self
  cursor = self

  unless op.nil?
    until cursor.tail?
      cursor = cursor.next
      svalue = svalue.send(op, cursor)
    end
  else
    until cursor.tail?
      cursor = cursor.next
      svalue = yield(svalue, cursor)
    end
  end

  svalue
end

#rejectObject

todo:

  • api: this always returns a cursor pointed at tail (ugh)

  • api: should be lazy

  • bug: doesn’t filter tail element



233
234
235
236
237
238
239
240
241
# File 'lib/fr/szipper/enumerable.rb', line 233

def reject
  cursor = self
  until cursor.tail?
    cursor = yield(cursor.node) ?
      cursor.replace(cursor.node.next) :
      cursor.next
  end
  cursor
end

#sortObject



245
246
247
# File 'lib/fr/szipper/enumerable.rb', line 245

def sort
  # todo: defined?
end

#take(n) ⇒ Object



249
250
251
# File 'lib/fr/szipper/enumerable.rb', line 249

def take(n)
  # todo: defined?
end

#take_whileObject



253
254
255
# File 'lib/fr/szipper/enumerable.rb', line 253

def take_while
  # todo: defined?
end

#zip(stream, *streams) ⇒ Object



259
260
261
# File 'lib/fr/szipper/enumerable.rb', line 259

def zip(stream, *streams)
  # todo: should be lazy
end