double_linked_list 0.1.0 → 0.2.0
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/.travis.yml +30 -2
- data/Gemfile +2 -0
- data/README.md +79 -9
- data/double_linked_list.gemspec +1 -0
- data/lib/double_linked_list/element.rb +100 -0
- data/lib/double_linked_list/sequence.rb +18 -0
- data/lib/double_linked_list/version.rb +1 -1
- data/lib/double_linked_list.rb +40 -32
- metadata +19 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2d32b4473a261613c917ec8481da96bc7eaca8e4
|
4
|
+
data.tar.gz: 60e714c5a3baf1318412f3c5817f373ddc0e6d57
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 885e97ebc16d00e86142e1c5bc4ca6a9d4b9e7528be2e7bba8d618b18f2b1a2bb80613a167673a6bccdf56142efceebc6189fb34265a1bd29186108a4201d721
|
7
|
+
data.tar.gz: 682228a274f17a1849fc1824ec71a3778f5b93b07739e0878e2ae3af74e996b80e42b0ac3c8fde4f2f932a360d4ed84e9939cc3b404cd3b0df8f26f76192d3fd
|
data/.travis.yml
CHANGED
@@ -1,5 +1,33 @@
|
|
1
1
|
sudo: false
|
2
|
+
cache: bundler
|
2
3
|
language: ruby
|
3
4
|
rvm:
|
4
|
-
- 2.
|
5
|
-
|
5
|
+
- 2.1
|
6
|
+
- 2.1.6
|
7
|
+
- 2.2
|
8
|
+
- 2.3.0
|
9
|
+
- ruby-head
|
10
|
+
- jruby-19mode
|
11
|
+
- jruby-9.0.1.0
|
12
|
+
- rbx-3
|
13
|
+
env:
|
14
|
+
# this doesn't do anything for MRI or RBX, but it doesn't hurt them either
|
15
|
+
# for JRuby, it enables us to get more accurate coverage data
|
16
|
+
- JRUBY_OPTS="--debug"
|
17
|
+
matrix:
|
18
|
+
allow_failures:
|
19
|
+
- rvm: ruby-head
|
20
|
+
- rvm: rbx-3
|
21
|
+
- rvm: jruby-19mode
|
22
|
+
- rvm: jruby-9.0.1.0
|
23
|
+
- rvm: 1.9.3
|
24
|
+
- rvm: 2.0.0
|
25
|
+
fast_finish: true
|
26
|
+
before_install: gem update --remote bundler
|
27
|
+
install:
|
28
|
+
- bundle install --retry=3
|
29
|
+
script:
|
30
|
+
- bundle exec rspec
|
31
|
+
addons:
|
32
|
+
code_climate:
|
33
|
+
repo_token: 9bc6cf480824676f6f459544eb93d3ad09b4a69e9b42c57c5e657748c38b779a
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# DoubleLinkedList
|
2
2
|
|
3
|
+
[](https://travis-ci.org/arturictus/double_linked_list)
|
4
|
+
[](https://badge.fury.io/rb/double_linked_list)
|
5
|
+
[](https://codeclimate.com/github/arturictus/double_linked_list)
|
6
|
+
[](https://codeclimate.com/github/arturictus/double_linked_list/coverage)
|
7
|
+
[](https://codeclimate.com/github/arturictus/double_linked_list)
|
8
|
+
|
3
9
|
The missing Ruby Linked list
|
4
10
|
|
5
11
|
## Installation
|
@@ -39,7 +45,7 @@ llist = DoubleLinkedList.from_a(1, 2, 3)
|
|
39
45
|
llist.last.datum #=> 3
|
40
46
|
```
|
41
47
|
|
42
|
-
__find:
|
48
|
+
__find:__
|
43
49
|
|
44
50
|
```ruby
|
45
51
|
llist = DoubleLinkedList.from_a(1, 2, 3)
|
@@ -50,13 +56,16 @@ llist.find(3).datum #=> 3
|
|
50
56
|
llist.find(9) #=> nil
|
51
57
|
```
|
52
58
|
|
53
|
-
|
54
|
-
|
59
|
+
__find_by:__
|
55
60
|
```ruby
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
61
|
+
User = Struct.new(:id)
|
62
|
+
users = [
|
63
|
+
User.new(1),
|
64
|
+
User.new(2),
|
65
|
+
User.new(3)
|
66
|
+
]
|
67
|
+
llist = DoubleLinkedList.from_a(users)
|
68
|
+
llist.find_by{ |elem| elem.datum.id == 1 }.datum.id #=> 1
|
60
69
|
```
|
61
70
|
|
62
71
|
__append:__
|
@@ -69,13 +78,74 @@ llist.last.next #=> be_nil
|
|
69
78
|
llist.last.previous.datum #=> 3
|
70
79
|
```
|
71
80
|
|
81
|
+
## Enumerable
|
82
|
+
|
83
|
+
- `map`
|
84
|
+
- `each`
|
85
|
+
- `reverse_each`
|
86
|
+
|
87
|
+
__each:__
|
88
|
+
```ruby
|
89
|
+
DoubleLinkedList.from_a(1, 2, 3).each { |e| puts e.datum }
|
90
|
+
# 1
|
91
|
+
# 2
|
92
|
+
# 3
|
93
|
+
```
|
94
|
+
|
95
|
+
__map:__
|
96
|
+
```ruby
|
97
|
+
DoubleLinkedList.from_a(1, 2, 3).map { |e| e.datum + 1}
|
98
|
+
#=> [2, 3, 4]
|
99
|
+
```
|
100
|
+
|
101
|
+
__reverse_each:__
|
102
|
+
```ruby
|
103
|
+
DoubleLinkedList.from_a(1, 2, 3).reverse_each { |e| puts e.datum }
|
104
|
+
# 3
|
105
|
+
# 2
|
106
|
+
# 1
|
107
|
+
```
|
108
|
+
|
109
|
+
__chunk_by:__
|
110
|
+
|
111
|
+
It will split the Double linked list in multiple linked list if the block
|
112
|
+
returns `truly`.
|
113
|
+
The first element of the splitted array are the elememts that return true in the block.
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
llist = DoubleLinkedList.from_a(1, 2, 3, 4)
|
117
|
+
chunked = llist.chunk_by do |e, current_llist|
|
118
|
+
e.datum == 3 && current_llist.head.datum == 1
|
119
|
+
end
|
120
|
+
chunked.first.is_a? DoubleLinkedList #=> true
|
121
|
+
chunked.first.head.datum #=> 1
|
122
|
+
chunked.first.last.datum #=> 2
|
123
|
+
chunked.map{|ll| ll.to_a } #=> [[1, 2], [3, 4]]
|
124
|
+
```
|
125
|
+
|
126
|
+
__select_by:__
|
127
|
+
|
128
|
+
For selecting fractions of the linked list avoiding the elements not returned in between the selected head and last sequences.
|
129
|
+
In the block must be returned a `DoubleLinkedList::Sequence` instance and head and last in the `DoubleLinkedList::Sequence` must be a `DoubleLinkedList::Element` (the element is passed to the block)
|
130
|
+
|
131
|
+
```ruby
|
132
|
+
llist = DoubleLinkedList.from_a(1, 2, 3, 4)
|
133
|
+
select = llist.select_by do |e|
|
134
|
+
if e.datum == 2 && e.next.datum == 3
|
135
|
+
DoubleLinkedList::Sequence.new(head: e, last: e.next)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
select.is_a? Array #=> true
|
139
|
+
select.first.is_a? DoubleLinkedList #=> true
|
140
|
+
select.map{|ll| ll.to_a } #=> [[2, 3]]
|
141
|
+
```
|
72
142
|
|
73
143
|
## Development
|
74
144
|
|
75
145
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake false ---` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
76
146
|
|
77
|
-
To install this gem onto your local machine, run `bundle exec rake install`.
|
147
|
+
To install this gem onto your local machine, run `bundle exec rake install`. [rubygems.org](https://rubygems.org).
|
78
148
|
|
79
149
|
## Contributing
|
80
150
|
|
81
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
151
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/arturictus/double_linked_list.
|
data/double_linked_list.gemspec
CHANGED
@@ -21,5 +21,6 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.12"
|
22
22
|
spec.add_development_dependency "rake", "~> 10.0"
|
23
23
|
spec.add_development_dependency "rspec", "~> 3.5"
|
24
|
+
spec.add_development_dependency "contextuable"
|
24
25
|
# spec.add_development_dependency "false ---", "~> "
|
25
26
|
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
class DoubleLinkedList
|
2
|
+
class Element < Struct.new(:datum, :previous, :_next)
|
3
|
+
include Enumerable
|
4
|
+
alias_method :next, :_next
|
5
|
+
alias_method :prev, :previous
|
6
|
+
|
7
|
+
def each(&block)
|
8
|
+
block.call self
|
9
|
+
_next.each(&block) if _next
|
10
|
+
end
|
11
|
+
|
12
|
+
def find(datum)
|
13
|
+
find_next_by do |elem|
|
14
|
+
elem.datum == datum
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def find_previous_by(&block)
|
19
|
+
_finder(:reverse_each, &block)
|
20
|
+
end
|
21
|
+
|
22
|
+
def find_next_by(&block)
|
23
|
+
_finder(:each, &block)
|
24
|
+
end
|
25
|
+
|
26
|
+
def reverse_each(&block)
|
27
|
+
block.call self
|
28
|
+
previous.reverse_each(&block) if previous
|
29
|
+
end
|
30
|
+
|
31
|
+
def append(datum)
|
32
|
+
new_last = Element.new(datum, self, nil)
|
33
|
+
self._next = new_last
|
34
|
+
new_last
|
35
|
+
end
|
36
|
+
|
37
|
+
def chunk_by(acc, &block)
|
38
|
+
if acc.empty?
|
39
|
+
acc << DoubleLinkedList.from_a(self.datum)
|
40
|
+
else
|
41
|
+
if block.call(self, acc.last, acc)
|
42
|
+
acc << DoubleLinkedList.from_a(self.datum)
|
43
|
+
else
|
44
|
+
acc.last << self.datum
|
45
|
+
end
|
46
|
+
end
|
47
|
+
_next ? _next.chunk_by(acc, &block) : acc
|
48
|
+
end
|
49
|
+
|
50
|
+
def select_by(acc, &block)
|
51
|
+
sequences = []
|
52
|
+
find_multiple do |e|
|
53
|
+
head_tail = block.call(e)
|
54
|
+
if head_tail
|
55
|
+
sequences << head_tail
|
56
|
+
end
|
57
|
+
head_tail
|
58
|
+
end
|
59
|
+
extract_sequences(sequences)
|
60
|
+
end
|
61
|
+
|
62
|
+
protected
|
63
|
+
|
64
|
+
def find_multiple(&block)
|
65
|
+
found = each_until_found(&block)
|
66
|
+
found.next.find_multiple(&block) if found && found.next?
|
67
|
+
end
|
68
|
+
|
69
|
+
def each_until_found(&block)
|
70
|
+
found = block.call(self)
|
71
|
+
return found if found
|
72
|
+
_next.each_until_found(&block) if _next
|
73
|
+
end
|
74
|
+
|
75
|
+
def extract_sequences(sequences)
|
76
|
+
sequences.each_with_object([]) do |seq, coll|
|
77
|
+
head = seq.head
|
78
|
+
head_datum = head.datum
|
79
|
+
list = DoubleLinkedList.from_a(head_datum)
|
80
|
+
last = nil
|
81
|
+
head.find_multiple do |elem|
|
82
|
+
next if head_datum == elem.datum
|
83
|
+
list << elem.datum
|
84
|
+
last = elem.datum if elem.datum == seq.last.datum
|
85
|
+
break if last
|
86
|
+
end
|
87
|
+
coll << list
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def _finder(direction, &block)
|
92
|
+
found = nil
|
93
|
+
send(direction) do |elem|
|
94
|
+
found = elem if block.call(elem)
|
95
|
+
break if found
|
96
|
+
end
|
97
|
+
found
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class DoubleLinkedList
|
2
|
+
class Sequence
|
3
|
+
attr_reader :head, :last
|
4
|
+
def initialize(head:, last:)
|
5
|
+
@head = head
|
6
|
+
@last = last
|
7
|
+
end
|
8
|
+
|
9
|
+
def next
|
10
|
+
return unless next?
|
11
|
+
last.next
|
12
|
+
end
|
13
|
+
|
14
|
+
def next?
|
15
|
+
last.next ? true : false
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/double_linked_list.rb
CHANGED
@@ -3,7 +3,17 @@ require 'forwardable'
|
|
3
3
|
class DoubleLinkedList
|
4
4
|
extend Forwardable
|
5
5
|
attr_accessor :head, :last
|
6
|
-
delegate [
|
6
|
+
delegate [
|
7
|
+
:datum,
|
8
|
+
:next,
|
9
|
+
:map,
|
10
|
+
:each,
|
11
|
+
:reduce,
|
12
|
+
] => :head
|
13
|
+
|
14
|
+
delegate [
|
15
|
+
:reverse_each,
|
16
|
+
] => :last
|
7
17
|
|
8
18
|
def initialize(datum)
|
9
19
|
@head = (datum.is_a?(Element) ? datum : Element.new(datum))
|
@@ -11,8 +21,9 @@ class DoubleLinkedList
|
|
11
21
|
|
12
22
|
class << self
|
13
23
|
def from_a(*ary)
|
14
|
-
|
15
|
-
|
24
|
+
elems = ary.flatten
|
25
|
+
head = Element.new(elems.first)
|
26
|
+
last = elems.drop(1).reduce(head) do |cur_last, datum|
|
16
27
|
cur_last.append(datum)
|
17
28
|
end
|
18
29
|
new(head).tap do |o|
|
@@ -24,46 +35,43 @@ class DoubleLinkedList
|
|
24
35
|
def append(datum)
|
25
36
|
self.last = last.append(datum)
|
26
37
|
end
|
27
|
-
|
38
|
+
alias_method :<<, :append
|
28
39
|
|
29
40
|
def find(datum)
|
30
|
-
|
31
|
-
|
32
|
-
found = elem if elem.datum == datum
|
33
|
-
break if found
|
41
|
+
find_by do |elem|
|
42
|
+
elem.datum == datum
|
34
43
|
end
|
35
|
-
found
|
36
44
|
end
|
37
45
|
|
38
|
-
def
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
46
|
+
def find_by(&block)
|
47
|
+
head.find_next_by(&block)
|
48
|
+
end
|
49
|
+
|
50
|
+
def reverse_find(datum)
|
51
|
+
reverse_find_by do |elem|
|
52
|
+
elem.datum == datum
|
43
53
|
end
|
44
|
-
found
|
45
54
|
end
|
46
55
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
alias_method :prev, :previous
|
56
|
+
def reverse_find_by(&block)
|
57
|
+
last.find_previous_by(&block)
|
58
|
+
end
|
51
59
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
end
|
60
|
+
def chunk_by(&block)
|
61
|
+
head.chunk_by([], &block)
|
62
|
+
end
|
56
63
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
end
|
61
|
-
alias_method :reverse_each, :each_from_last
|
64
|
+
def select_by(&block)
|
65
|
+
head.select_by([], &block)
|
66
|
+
end
|
62
67
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
new_last
|
68
|
+
def to_a
|
69
|
+
[].tap do |ary|
|
70
|
+
each{ |elem| ary << elem.datum }
|
67
71
|
end
|
68
72
|
end
|
73
|
+
|
69
74
|
end
|
75
|
+
|
76
|
+
require 'double_linked_list/element'
|
77
|
+
require 'double_linked_list/sequence'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: double_linked_list
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Artur Pañach
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-11-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '3.5'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: contextuable
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
description: The missing Ruby Double Linked List.
|
56
70
|
email:
|
57
71
|
- arturictus@gmail.com
|
@@ -69,6 +83,8 @@ files:
|
|
69
83
|
- bin/setup
|
70
84
|
- double_linked_list.gemspec
|
71
85
|
- lib/double_linked_list.rb
|
86
|
+
- lib/double_linked_list/element.rb
|
87
|
+
- lib/double_linked_list/sequence.rb
|
72
88
|
- lib/double_linked_list/version.rb
|
73
89
|
homepage: https://github.com/arturictus/double_linked_list
|
74
90
|
licenses: []
|
@@ -89,7 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
89
105
|
version: '0'
|
90
106
|
requirements: []
|
91
107
|
rubyforge_project:
|
92
|
-
rubygems_version: 2.
|
108
|
+
rubygems_version: 2.2.3
|
93
109
|
signing_key:
|
94
110
|
specification_version: 4
|
95
111
|
summary: The missing Ruby Double Linked List
|