Линейный двусвязный список. Вдохновлен, как говорят на гитхабе, статьей
https://medium.com/p/3beb48ff49cd.
// class DoublyLinkedList constructor
function DoublyLinkedList() {
this.size = 0;
this.head = null;
this.tail = null;
}
// class DoublyLinkedList.Node constructor
DoublyLinkedList.Node = function (data) {
this.data = data;
this.next = null;
this.prev = null;
};
// class DoublyLinkedList methods
DoublyLinkedList.prototype.insert = function (data, reverse) {
var node = new DoublyLinkedList.Node(data);
if (reverse) {
if (this.head !== null) {
node.next = this.head;
this.head.prev = node;
}
this.head = node;
if (this.tail === null) {
this.tail = node;
}
} else {
if (this.tail !== null) {
node.prev = this.tail;
this.tail.next = node;
}
this.tail = node;
if (this.head === null) {
this.head = node;
}
}
this.size++;
return node;
};
DoublyLinkedList.prototype.delete = function (data) {
var node = this.head;
while (node !== null) {
if (node.data === data) {
var prev = node.prev, next = node.next;
if (prev !== null) {
prev.next = next;
} else {
this.head = next;
}
if (next !== null) {
next.prev = prev;
} else {
this.tail = prev;
}
this.size--;
break;
}
node = node.next;
}
return node;
};
DoublyLinkedList.prototype.forEach = function (callback, reverse) {
if (reverse) {
var node = this.tail;
while (node !== null) {
callback.call(this, node.data);
node = node.prev;
}
} else {
var node = this.head;
while (node !== null) {
callback.call(this, node.data);
node = node.next;
}
}
return this;
};
DoublyLinkedList.prototype.toArray = function (stringify) {
var node = this.head, array = [];
while (node !== null) {
array.push(node.data);
node = node.next;
}
return stringify ? JSON.stringify(array) : array;
};
DoublyLinkedList.prototype.toDocument = function (parent) {
var node = this.head, ol = document.createElement('ol');
while (node !== null) {
node.data.toDocument(ol);
node = node.next;
}
return parent.appendChild(ol);
};
// class Apartment constructor
function Apartment(prop1, prop2, prop3, prop4) {
this.prop1 = prop1;
this.prop2 = prop2;
this.prop3 = prop3;
this.prop4 = prop4;
}
// class Apartment methods
Apartment.prototype.compare = function (apartment) {
var prop3 = this.prop3 / apartment.prop3;
return (this.prop1 == apartment.prop1) &&
(this.prop2 == apartment.prop2) &&
(0.9 < prop3 && prop3 < 1.1);
};
Apartment.prototype.toDocument = function (parent) {
var li = document.createElement('li');
li.textContent = JSON.stringify(this);
return parent.appendChild(li);
};
// Usage
var apartmentList = new DoublyLinkedList();
var apartmentListNode = new DoublyLinkedList.Node();
var apartment1 = new Apartment(1, 1, 1, '1');
var apartment2 = new Apartment(2, 2, 2, '2');
var apartment3 = new Apartment(3, 3, 3, '3');
var tailinsertedNode1 = apartmentList.insert(apartment1);
var tailinsertedNode2 = apartmentList.insert(apartment2);
var headinsertedNode3 = apartmentList.insert(apartment3, true);
var deletedNode = apartmentList.delete(apartment2);
var thisList = apartmentList.forEach(function (apartment) {
if (apartment2.compare(apartment)) this.remove(apartment);
});
var nodeDataArray = apartmentList.toArray();
var stringifiedArray = apartmentList.toArray(true);
var olElement = apartmentList.toDocument(document.body);
var liElement = apartmentList.insert(apartment2).data.toDocument(olElement);