@@ -10,14 +10,15 @@ const Err = require('../misc/Errors');
10
10
class OneLinkList {
11
11
/**
12
12
* OneLinkList constructor.
13
+ * @param {any } data - The data for the first item in the list to hold.
13
14
*/
14
15
constructor ( data ) {
15
16
// List properties.
16
17
this . count = 0 ;
17
- this . first = new Item ( ) ;
18
- this . last = new Item ( ) ;
18
+ this . first = null ;
19
+ this . last = null ;
19
20
20
- // Check if first item was passed as data .
21
+ // Check if first item data was passed.
21
22
if ( data !== undefined ) {
22
23
this . AddToEnd ( data ) ;
23
24
}
@@ -39,30 +40,29 @@ class Item {
39
40
}
40
41
}
41
42
42
- // exports.TwoLinkList = class TwoLinkList {
43
- // constructor() {
44
- // console.log('In the TwoLinkList default ctor.\n')
45
- // }
46
- // }
47
-
48
43
/**
49
44
* Method to add a new item to the end of the list.
50
45
* @param {any } data - The data the new item holds.
51
46
*/
52
47
OneLinkList . prototype . AddToEnd = function ( data ) {
53
- let newNode = new Item ( data ) ,
54
- currNode = this . first ;
48
+ // Check if valid data was passed as an argument.
49
+ if ( data === undefined ) {
50
+ throw new Err . DSException ( Err . ListErr . InvalidData ( ) , 301 ) ;
51
+ }
52
+
53
+ let newItem = new Item ( data ) ,
54
+ currItem = this . first ;
55
55
56
- if ( this . count == 0 ) {
57
- this . first = newNode ;
56
+ if ( this . count === 0 ) {
57
+ this . first = newItem ;
58
58
this . last = this . first ;
59
59
} else {
60
- while ( currNode . next != null ) {
61
- currNode = currNode . next ;
60
+ while ( currItem . next != = null ) {
61
+ currItem = currItem . next ;
62
62
}
63
63
64
- currNode . next = newNode ;
65
- this . last = newNode ;
64
+ currItem . next = newItem ;
65
+ this . last = newItem ;
66
66
}
67
67
68
68
this . count ++ ;
@@ -76,11 +76,11 @@ OneLinkList.prototype.FindAt = function(position) {
76
76
// Show error when trying to access position outside of list.
77
77
if ( this . count === 0 || position > this . count || position < 1 ) {
78
78
throw new Err . DSException ( Err . ListErr . NonExistant ( OneLinkList . name ) , 101 ) ;
79
- } else if ( position % 1 != 0 || typeof ( position ) != Number . name . toLowerCase ( ) ) {
79
+ } else if ( position % 1 != 0 || typeof position != Number . name . toLowerCase ( ) ) {
80
80
throw new Err . DSException ( Err . ListErr . InvalidPosition ( ) , 102 ) ;
81
81
}
82
82
83
- // Linearly search for item (1 -> last).
83
+ // Sequentially search for item (1 -> last).
84
84
let currItem = this . first ;
85
85
for ( let currCount = 1 ; currCount < position ; currCount ++ ) {
86
86
currItem = currItem . next ;
@@ -97,7 +97,9 @@ OneLinkList.prototype.RemoveAt = function(position) {
97
97
// Show error when trying to access position outside of list.
98
98
if ( this . count === 0 || position > this . count || position < 1 ) {
99
99
throw new Err . DSException ( Err . ListErr . NonExistant ( OneLinkList . name ) , 201 ) ;
100
- } else if ( position % 1 != 0 || typeof ( position ) != Number . name . toLowerCase ( ) ) {
100
+ }
101
+ // Show error when the position is invalid.
102
+ else if ( position % 1 != 0 || typeof ( position ) != Number . name . toLowerCase ( ) ) {
101
103
throw new Err . DSException ( Err . ListErr . InvalidPosition ( ) , 202 ) ;
102
104
}
103
105
@@ -115,6 +117,77 @@ OneLinkList.prototype.RemoveAt = function(position) {
115
117
this . count -- ;
116
118
}
117
119
120
+ /**
121
+ * Removes the first item matching the data passed.
122
+ * @param {any } data - The data to search and destroy.
123
+ */
124
+ OneLinkList . prototype . RemoveThis = function ( data ) {
125
+ // Check if the list is empty.
126
+ if ( this . count === 0 ) {
127
+ throw new Err . DSException ( Err . ListErr . NonExistant ( OneLinkList . name ) , 401 ) ;
128
+ }
129
+ // Check if valid data was passed as an argument.
130
+ else if ( data === undefined ) {
131
+ throw new Err . DSException ( Err . ListErr . InvalidData ( ) , 402 ) ;
132
+ }
133
+
134
+ // Search through list sequentially for the data.
135
+ let currItem = this . first ,
136
+ itemToRemove ;
137
+
138
+ // Handle list with one item.
139
+ if ( this . count === 1 ) {
140
+ if ( typeof ( data ) == 'object' ) {
141
+ if ( JSON . stringify ( currItem . data ) === JSON . stringify ( data ) ) {
142
+ this . first = null ;
143
+ this . last = null ;
144
+ this . count -- ;
145
+ return ;
146
+ }
147
+ } else {
148
+ if ( currItem . data === data ) {
149
+ this . first = null ;
150
+ this . last = null ;
151
+ this . count -- ;
152
+ return ;
153
+ }
154
+ }
155
+ }
156
+ // Handle list with more than one item.
157
+ else {
158
+ // If data param is an object.
159
+ if ( typeof ( data ) == 'object' ) {
160
+ while ( currItem . next ) {
161
+ if ( JSON . stringify ( currItem . next . data ) === JSON . stringify ( data ) ) {
162
+ itemToRemove = currItem . next ;
163
+ currItem . next = currItem . next . next ;
164
+ break ;
165
+ }
166
+
167
+ currItem = currItem . next ;
168
+ }
169
+ }
170
+ // Else data param is a non-reference data type.
171
+ else {
172
+ while ( currItem . next ) {
173
+ if ( currItem . next . data === data ) {
174
+ itemToRemove = currItem . next ;
175
+ currItem . next = currItem . next . next ;
176
+ break ;
177
+ }
178
+
179
+ currItem = currItem . next ;
180
+ }
181
+ }
182
+ }
183
+
184
+ delete itemToRemove ;
185
+ }
186
+
187
+ /**
188
+ * Checks if the list has an item with the passed data.
189
+ * @param {any } data - The data to check for.
190
+ */
118
191
OneLinkList . prototype . Contains = function ( data ) {
119
192
// Check if valid data was passed as an argument.
120
193
if ( ! data ) {
@@ -154,17 +227,26 @@ OneLinkList.prototype.Contains = function(data) {
154
227
* Print all items of the list to the console.
155
228
*/
156
229
OneLinkList . prototype . PrintAll = function ( ) {
230
+ // Check if the list is empty.
231
+ if ( this . count === 0 || ! ( this . first instanceof Item ) ) {
232
+ console . log ( 'Empty list.' ) ;
233
+ return ;
234
+ }
235
+
236
+ // Print each item to the console.
157
237
let curr = this . first ;
158
- while ( curr . next ) {
238
+ while ( curr ) {
159
239
console . log ( curr ) ;
160
240
curr = curr . next ;
161
241
}
162
- console . log ( curr ) ;
163
242
}
164
243
165
244
/**
166
245
* All linked list exports.
167
246
*/
168
- module . exports = {
169
- OneLinkList : OneLinkList ,
170
- }
247
+ module . exports = OneLinkList ;
248
+
249
+ // Use below if exporting multiple items.
250
+ // module.exports = {
251
+ // OneLinkList: OneLinkList,
252
+ // }
0 commit comments