Ответ 1
Создайте структуру данных самостоятельно. Сохраните порядок в массиве, который является внутренним для структуры. Храните объекты, сопоставленные ключом в обычном объекте. Позвольте называть его OrderedMap
, который будет иметь карту, массив и четыре основных метода.
OrderedMap
map
_array
set(key, value)
get(key)
remove(key)
forEach(fn)
function OrderedMap() {
this.map = {};
this._array = [];
}
При вставке элемента добавьте его в массив в нужном месте, а также в объект. Вставка по индексу или в конце находится в O (1).
OrderedMap.prototype.set = function(key, value) {
// key already exists, replace value
if(key in this.map) {
this.map[key] = value;
}
// insert new key and value
else {
this._array.push(key);
this.map[key] = value;
}
};
При удалении объекта удалите его из массива и объекта. Если удалить ключ или значение, сложность - это O (n), так как вам нужно пройти через внутренний массив, который поддерживает упорядочение. При удалении по индексу сложность - это O (1), поскольку у вас есть прямой доступ к значению как в массиве, так и в объекте.
OrderedMap.prototype.remove = function(key) {
var index = this._array.indexOf(key);
if(index == -1) {
throw new Error('key does not exist');
}
this._array.splice(index, 1);
delete this.map[key];
};
Поиск будет в O (1). Получить значение по ключу из ассоциативного массива (объекта).
OrderedMap.prototype.get = function(key) {
return this.map[key];
};
Траверс будет упорядочен и может использовать любой из подходов. Когда требуется упорядоченное обход, создайте массив с объектами (только значения) и верните его. Будучи массивом, он не будет поддерживать доступ с ключом. Другой вариант - попросить клиента предоставить функцию обратного вызова, которая должна применяться к каждому объекту в массиве.
OrderedMap.prototype.forEach = function(f) {
var key, value;
for(var i = 0; i < this._array.length; i++) {
key = this._array[i];
value = this.map[key];
f(key, value);
}
};
См. реализацию Google LinkedMap из библиотеки Closure для документации и источника для такого класса.