2 module.exports = Yallist
5 Yallist.create = Yallist
7 function Yallist (list) {
9 if (!(self instanceof Yallist)) {
17 if (list && typeof list.forEach === 'function') {
18 list.forEach(function (item) {
21 } else if (arguments.length > 0) {
22 for (var i = 0, l = arguments.length; i < l; i++) {
23 self.push(arguments[i])
30 Yallist.prototype.removeNode = function (node) {
31 if (node.list !== this) {
32 throw new Error('removing node which does not belong to this list')
46 if (node === this.head) {
49 if (node === this.tail) {
61 Yallist.prototype.unshiftNode = function (node) {
62 if (node === this.head) {
67 node.list.removeNode(node)
84 Yallist.prototype.pushNode = function (node) {
85 if (node === this.tail) {
90 node.list.removeNode(node)
107 Yallist.prototype.push = function () {
108 for (var i = 0, l = arguments.length; i < l; i++) {
109 push(this, arguments[i])
114 Yallist.prototype.unshift = function () {
115 for (var i = 0, l = arguments.length; i < l; i++) {
116 unshift(this, arguments[i])
121 Yallist.prototype.pop = function () {
126 var res = this.tail.value
127 this.tail = this.tail.prev
129 this.tail.next = null
137 Yallist.prototype.shift = function () {
142 var res = this.head.value
143 this.head = this.head.next
145 this.head.prev = null
153 Yallist.prototype.forEach = function (fn, thisp) {
154 thisp = thisp || this
155 for (var walker = this.head, i = 0; walker !== null; i++) {
156 fn.call(thisp, walker.value, i, this)
161 Yallist.prototype.forEachReverse = function (fn, thisp) {
162 thisp = thisp || this
163 for (var walker = this.tail, i = this.length - 1; walker !== null; i--) {
164 fn.call(thisp, walker.value, i, this)
169 Yallist.prototype.get = function (n) {
170 for (var i = 0, walker = this.head; walker !== null && i < n; i++) {
171 // abort out of the list early if we hit a cycle
174 if (i === n && walker !== null) {
179 Yallist.prototype.getReverse = function (n) {
180 for (var i = 0, walker = this.tail; walker !== null && i < n; i++) {
181 // abort out of the list early if we hit a cycle
184 if (i === n && walker !== null) {
189 Yallist.prototype.map = function (fn, thisp) {
190 thisp = thisp || this
191 var res = new Yallist()
192 for (var walker = this.head; walker !== null;) {
193 res.push(fn.call(thisp, walker.value, this))
199 Yallist.prototype.mapReverse = function (fn, thisp) {
200 thisp = thisp || this
201 var res = new Yallist()
202 for (var walker = this.tail; walker !== null;) {
203 res.push(fn.call(thisp, walker.value, this))
209 Yallist.prototype.reduce = function (fn, initial) {
211 var walker = this.head
212 if (arguments.length > 1) {
214 } else if (this.head) {
215 walker = this.head.next
216 acc = this.head.value
218 throw new TypeError('Reduce of empty list with no initial value')
221 for (var i = 0; walker !== null; i++) {
222 acc = fn(acc, walker.value, i)
229 Yallist.prototype.reduceReverse = function (fn, initial) {
231 var walker = this.tail
232 if (arguments.length > 1) {
234 } else if (this.tail) {
235 walker = this.tail.prev
236 acc = this.tail.value
238 throw new TypeError('Reduce of empty list with no initial value')
241 for (var i = this.length - 1; walker !== null; i--) {
242 acc = fn(acc, walker.value, i)
249 Yallist.prototype.toArray = function () {
250 var arr = new Array(this.length)
251 for (var i = 0, walker = this.head; walker !== null; i++) {
252 arr[i] = walker.value
258 Yallist.prototype.toArrayReverse = function () {
259 var arr = new Array(this.length)
260 for (var i = 0, walker = this.tail; walker !== null; i++) {
261 arr[i] = walker.value
267 Yallist.prototype.slice = function (from, to) {
268 to = to || this.length
276 var ret = new Yallist()
277 if (to < from || to < 0) {
283 if (to > this.length) {
286 for (var i = 0, walker = this.head; walker !== null && i < from; i++) {
289 for (; walker !== null && i < to; i++, walker = walker.next) {
290 ret.push(walker.value)
295 Yallist.prototype.sliceReverse = function (from, to) {
296 to = to || this.length
304 var ret = new Yallist()
305 if (to < from || to < 0) {
311 if (to > this.length) {
314 for (var i = this.length, walker = this.tail; walker !== null && i > to; i--) {
317 for (; walker !== null && i > from; i--, walker = walker.prev) {
318 ret.push(walker.value)
323 Yallist.prototype.splice = function (start, deleteCount, ...nodes) {
324 if (start > this.length) {
325 start = this.length - 1
328 start = this.length + start;
331 for (var i = 0, walker = this.head; walker !== null && i < start; i++) {
336 for (var i = 0; walker && i < deleteCount; i++) {
337 ret.push(walker.value)
338 walker = this.removeNode(walker)
340 if (walker === null) {
344 if (walker !== this.head && walker !== this.tail) {
348 for (var i = 0; i < nodes.length; i++) {
349 walker = insert(this, walker, nodes[i])
354 Yallist.prototype.reverse = function () {
357 for (var walker = head; walker !== null; walker = walker.prev) {
359 walker.prev = walker.next
367 function insert (self, node, value) {
368 var inserted = node === self.head ?
369 new Node(value, null, node, self) :
370 new Node(value, node, node.next, self)
372 if (inserted.next === null) {
375 if (inserted.prev === null) {
384 function push (self, item) {
385 self.tail = new Node(item, self.tail, null, self)
387 self.head = self.tail
392 function unshift (self, item) {
393 self.head = new Node(item, null, self.head, self)
395 self.tail = self.head
400 function Node (value, prev, next, list) {
401 if (!(this instanceof Node)) {
402 return new Node(value, prev, next, list)
424 // add if support for Symbol.iterator is present
425 require('./iterator.js')(Yallist)