linked 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -0
- data/lib/linked/item.rb +7 -7
- data/lib/linked/list.rb +120 -40
- data/lib/linked/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ea4e0ba7b896f4e64d885d73066e65e4e08b49ea
|
4
|
+
data.tar.gz: 7913edd077d33d5a7b36982568d5b3cb46cc7c1e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1467066f7e5af4ddc7eca82013d94777b956d7c93497502977fd776523e570bb7ae0d441940cb9a275f567c48750a50cff80881de98e1ca89c1592b7a5aff599
|
7
|
+
data.tar.gz: fac1a3393906af1c00f788fbc4e5eb30ab2b48e042190f898b43944a6ae4718baec62b9c0e0193537cc4f484f4a518f435abf0a7611bb5f28215d6aa8128b54f
|
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# Linked
|
2
2
|
|
3
|
+
[](https://badge.fury.io/rb/linked)
|
3
4
|
[](https://travis-ci.org/seblindberg/ruby-linked)
|
4
5
|
[](https://coveralls.io/github/seblindberg/ruby-linked?branch=master)
|
5
6
|
[](http://inch-ci.org/github/seblindberg/ruby-linked)
|
data/lib/linked/item.rb
CHANGED
@@ -56,12 +56,12 @@ module Linked
|
|
56
56
|
@prev = nil
|
57
57
|
end
|
58
58
|
end
|
59
|
-
|
59
|
+
|
60
60
|
# Calling #dup on an item returns a copy that is no longer connected to the
|
61
61
|
# original item chain, or the list. The value will also be copied.
|
62
62
|
#
|
63
63
|
# Returns a new Item.
|
64
|
-
|
64
|
+
|
65
65
|
def initialize_dup(source)
|
66
66
|
@next = @prev = @list = nil
|
67
67
|
@value = begin
|
@@ -326,21 +326,21 @@ module Linked
|
|
326
326
|
item = item.next
|
327
327
|
end
|
328
328
|
end
|
329
|
-
|
329
|
+
|
330
330
|
# Freezes the value, as well as making the list item itself immutable.
|
331
|
-
|
331
|
+
|
332
332
|
def freeze
|
333
333
|
value.freeze
|
334
334
|
super
|
335
335
|
end
|
336
|
-
|
336
|
+
|
337
337
|
# The default #inspect method becomes very cluttered the moment you start
|
338
338
|
# liking objects together. This implementation fixes that and only shows the
|
339
339
|
# class name, object id and value (if set).
|
340
|
-
|
340
|
+
|
341
341
|
def inspect
|
342
342
|
return yield self if block_given?
|
343
|
-
|
343
|
+
|
344
344
|
output = format '%s:0x%0x', self.class.name, object_id
|
345
345
|
value ? output + " value=#{value.inspect}" : output
|
346
346
|
end
|
data/lib/linked/list.rb
CHANGED
@@ -46,67 +46,81 @@ module Linked
|
|
46
46
|
def initialize(*)
|
47
47
|
@eol = EOL.new list: self
|
48
48
|
@item_count = 0
|
49
|
-
|
49
|
+
|
50
50
|
super
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
# When copying a list its entire item chain needs to be copied as well.
|
54
54
|
# Therefore #dup will be called on each of the original lists items, making
|
55
55
|
# this operation quite expensive.
|
56
|
-
|
56
|
+
|
57
57
|
def initialize_dup(source)
|
58
58
|
@eol = EOL.new list: self
|
59
59
|
@item_count = 0
|
60
|
-
|
60
|
+
|
61
61
|
source.each_item { |item| push item.dup }
|
62
|
-
|
62
|
+
|
63
63
|
super
|
64
64
|
end
|
65
65
|
|
66
|
-
# Access the first n item(s) in the list.
|
66
|
+
# Access the first n item(s) in the list. If a block is given each item will
|
67
|
+
# be yielded to it. The first item, starting from the first in the list, for
|
68
|
+
# which the block returns true and the n - 1 items directly following it
|
69
|
+
# will be returned.
|
67
70
|
#
|
68
71
|
# n - the number of items to return.
|
69
72
|
#
|
70
|
-
# Returns
|
73
|
+
# Returns, for different values of n:
|
74
|
+
# n == 0) nil
|
75
|
+
# n == 1) an item if the list contains one, or nil
|
76
|
+
# n > 1) an array of between 0 and n items, depending on how many are in
|
77
|
+
# the list
|
71
78
|
|
72
|
-
def first(
|
73
|
-
if
|
74
|
-
|
75
|
-
|
76
|
-
|
79
|
+
def first(n = 1)
|
80
|
+
raise ArgumentError, 'n cannot be negative' if n < 0
|
81
|
+
|
82
|
+
return first_item_after eol, count, n unless block_given?
|
83
|
+
|
84
|
+
item = eol
|
85
|
+
items_left = count
|
86
|
+
|
87
|
+
items_left.times do
|
88
|
+
break if yield next_item = item.next
|
89
|
+
item = next_item
|
90
|
+
items_left -= 1
|
77
91
|
end
|
92
|
+
|
93
|
+
first_item_after item, items_left, n
|
78
94
|
end
|
79
95
|
|
80
|
-
# Access the last n item(s) in the list.
|
81
|
-
#
|
82
|
-
#
|
83
|
-
#
|
84
|
-
# the behaviour of #first. Negative values will raise an ArgumentError.
|
96
|
+
# Access the last n item(s) in the list. The items will retain thier order.
|
97
|
+
# If a block is given each item, starting with the last in the list, will be
|
98
|
+
# yielded to it. The first item for which the block returns true and the
|
99
|
+
# n - 1 items directly preceding it will be returned.
|
85
100
|
#
|
86
101
|
# n - the number of items to return.
|
87
102
|
#
|
88
|
-
# Returns
|
103
|
+
# Returns, for different values of n:
|
104
|
+
# n == 0) nil
|
105
|
+
# n == 1) an item if the list contains one, or nil
|
106
|
+
# n > 1) an array of between 0 and n items, depending on how many are in
|
107
|
+
# the list
|
89
108
|
|
90
109
|
def last(n = 1)
|
91
|
-
if n
|
92
|
-
eol.prev!
|
93
|
-
else
|
94
|
-
raise ArgumentError, 'n cannot be negative' if n < 0
|
95
|
-
|
96
|
-
n = count if n > count
|
97
|
-
res = Array.new n
|
110
|
+
raise ArgumentError, 'n cannot be negative' if n < 0
|
98
111
|
|
99
|
-
|
112
|
+
return last_item_before eol, count, n unless block_given?
|
100
113
|
|
101
|
-
|
102
|
-
|
103
|
-
n -= 1
|
104
|
-
res[n] = item
|
105
|
-
item = item.prev
|
106
|
-
end
|
114
|
+
item = eol
|
115
|
+
items_left = count
|
107
116
|
|
108
|
-
|
117
|
+
items_left.times do
|
118
|
+
break if yield prev_item = item.prev
|
119
|
+
item = prev_item
|
120
|
+
items_left -= 1
|
109
121
|
end
|
122
|
+
|
123
|
+
last_item_before item, items_left, n
|
110
124
|
end
|
111
125
|
|
112
126
|
# Overrides the Enumerable#count method when given no argument to provide a
|
@@ -184,21 +198,32 @@ module Linked
|
|
184
198
|
# Iterates over each item in the list, either in normal or reverse order. If
|
185
199
|
# a block is not given an enumerator is returned.
|
186
200
|
#
|
187
|
-
# reverse - flips the iteration order if true.
|
201
|
+
# reverse - flips the iteration order if true. Note that this option is
|
202
|
+
# depricated and will be removed in the next major release.
|
188
203
|
|
189
204
|
def each_item(reverse: false, &block)
|
190
205
|
if reverse
|
206
|
+
warn '[DEPRECATION] the option `reverse: true` will be removed in a future release. Please call `reverse_each_item` instead.'
|
191
207
|
eol.before(&block)
|
192
208
|
else
|
193
209
|
eol.after(&block)
|
194
210
|
end
|
195
211
|
end
|
196
|
-
|
212
|
+
|
197
213
|
alias each each_item
|
198
|
-
|
214
|
+
|
215
|
+
# Iterates over each item in the list in reverse order. If a block is not
|
216
|
+
# given an enumerator is returned.
|
217
|
+
|
218
|
+
def reverse_each_item(&block)
|
219
|
+
eol.before(&block)
|
220
|
+
end
|
221
|
+
|
222
|
+
alias reverse_each reverse_each_item
|
223
|
+
|
199
224
|
# Calls #freeze on all items in the list, as well as the head and the tail
|
200
225
|
# (eol).
|
201
|
-
|
226
|
+
|
202
227
|
def freeze
|
203
228
|
eol.freeze
|
204
229
|
each_item(&:freeze)
|
@@ -214,15 +239,15 @@ module Linked
|
|
214
239
|
def inspect(&block)
|
215
240
|
# Get the parents inspect output
|
216
241
|
res = [super]
|
217
|
-
|
242
|
+
|
218
243
|
each_item do |item|
|
219
244
|
lines = item.inspect(&block).split "\n"
|
220
|
-
|
245
|
+
|
221
246
|
res.push (item.last? ? '└─╴' : '├─╴') + lines.shift
|
222
247
|
padding = item.last? ? ' ' : '│ '
|
223
248
|
lines.each { |line| res.push padding + line }
|
224
249
|
end
|
225
|
-
|
250
|
+
|
226
251
|
res.join("\n")
|
227
252
|
end
|
228
253
|
|
@@ -247,5 +272,60 @@ module Linked
|
|
247
272
|
private def shrink(n = 1)
|
248
273
|
@item_count -= n
|
249
274
|
end
|
275
|
+
|
276
|
+
# Private helper method that returns the first n items, starting just after
|
277
|
+
# item, given that there are items_left items left. The following must hold
|
278
|
+
# for the output to be valid:
|
279
|
+
# a) n > 0
|
280
|
+
# b) there are at least items_left items left
|
281
|
+
#
|
282
|
+
# item - the Item just before the item to start from
|
283
|
+
# items_left - the number of items left.
|
284
|
+
# n - the number of items to return.
|
285
|
+
#
|
286
|
+
# Returns, for different values of n:
|
287
|
+
# n == 0) nil
|
288
|
+
# n == 1) an item if items_left > 0 or nil
|
289
|
+
# n > 1) an array of items if items_left > 0 or an empty array
|
290
|
+
|
291
|
+
private def first_item_after(item, items_left, n)
|
292
|
+
# Optimize for these cases
|
293
|
+
return nil if n == 0
|
294
|
+
return item.next if n == 1
|
295
|
+
|
296
|
+
(n > items_left ? items_left : n).times.map { item = item.next }
|
297
|
+
rescue StopIteration
|
298
|
+
n > 1 ? [] : nil
|
299
|
+
end
|
300
|
+
|
301
|
+
# Private helper method that returns the last n items, ending just before
|
302
|
+
# item, given that there are items_left items left. The following must hold
|
303
|
+
# for the output to be valid:
|
304
|
+
# a) n > 0
|
305
|
+
# b) there are at least items_left items left
|
306
|
+
#
|
307
|
+
# item - the Item just after the item to start from.
|
308
|
+
# items_left - the number of items left.
|
309
|
+
# n - the number of items to return.
|
310
|
+
#
|
311
|
+
# Returns, for different values of n:
|
312
|
+
# n == 0) nil
|
313
|
+
# n == 1) an item if items_left > 0 or nil
|
314
|
+
# n > 1) an array of items if items_left > 0 or an empty array
|
315
|
+
|
316
|
+
private def last_item_before(item, items_left, n)
|
317
|
+
# Optimize for these cases
|
318
|
+
return nil if n == 0
|
319
|
+
return item.prev if n == 1
|
320
|
+
|
321
|
+
# Truncate n if it is larger than the number of items
|
322
|
+
# left
|
323
|
+
n = (n > items_left ? items_left : n)
|
324
|
+
(n - 1).downto(0).with_object(Array.new n) do |i, arr|
|
325
|
+
arr[i] = item = item.prev
|
326
|
+
end
|
327
|
+
rescue StopIteration
|
328
|
+
n > 1 ? [] : nil
|
329
|
+
end
|
250
330
|
end
|
251
331
|
end
|
data/lib/linked/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: linked
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sebastian Lindberg
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-08-
|
11
|
+
date: 2016-08-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|