linked 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Gem Version](https://badge.fury.io/rb/linked.svg)](https://badge.fury.io/rb/linked)
|
3
4
|
[![Build Status](https://travis-ci.org/seblindberg/ruby-linked.svg?branch=master)](https://travis-ci.org/seblindberg/ruby-linked)
|
4
5
|
[![Coverage Status](https://coveralls.io/repos/github/seblindberg/ruby-linked/badge.svg?branch=master)](https://coveralls.io/github/seblindberg/ruby-linked?branch=master)
|
5
6
|
[![Inline docs](http://inch-ci.org/github/seblindberg/ruby-linked.svg?branch=master)](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
|