У меня есть потребность в объекте типа списка, одновременно обеспечивая противоположное поведение массива JS, являющееся итерабельным и ассоциативным. Поэтому в какой-то момент я хочу запустить основанную на индексах прохождение через члены, а в другой, которую я хочу сделать, "существует ли этот ключ" и "обновлять данные под этим ключом".
Я вижу много вопросов в отношении обсуждений ассоциативных массивов, но этот вопрос отличается тем, что я ищу повторно используемый код, который обертывает оба поведения. Решение может быть модификатором прототипа массива или автономной функцией создания объекта. Я признаю, что список должен быть уникальным по ключевому слову, а FYI - в моем случае члены будут самими объектами.
Обратите внимание: я знаю, что в JavaScript нет такой вещи, как ассоциативный массив - мне не нужна эта проповедь. Я ищу решение для одного объекта с двумя возможностями в одном списке.
Вот рудиментарная версия в рабочем фрагменте. Я ищу более сложную версию, которая включает полный набор функций жизненного цикла, таких как утилизация и т.д.
var List = function() {
this.elements={} // assoc list of elements.
this.elementArray=[] // plain array
this.addElement=function (id, member) {
this.elements[id]=member;
this.elementArray.push(member);
}
}
var myList = new List();
myList.addElement('V', {id: 'key2', name: 'Volvo'});
myList.addElement('A', {id: 'key4', name: 'Apple'});
myList.addElement('S', {id: 'key3', name: 'Google'});
console.log('Via iteration');
for (var i = 0; i < myList.elementArray.length; i = i + 1) {
console.log('id=' + myList.elementArray[i].id + ' name=' + myList.elementArray[i].name);
}
console.log('Via association');
console.log('Value of A: id=' + myList.elements['A'].id + ' name=' + myList.elements['A'].name);
console.log('Value of V: id=' + myList.elements['V'].id + ' name=' + myList.elements['V'].name);
console.log('Value of S: id=' + myList.elements['S'].id + ' name=' + myList.elements['S'].name);
Я знаю, что это далеко от завершения, но это может дать вам отправную точку, расширение класса Array
дает вам свойство специальной length
массива (добавляет в push, когда его модифицирует, он модифицирует сам массив и т.д.),
'use strict';
class AssociativeArray extends Array {
constructor() {
super();
this.data = {};
}
push(key, value) {
super.push(key);
this.data[key] = value
}
*[Symbol.iterator]() {
let nextIndex = 0;
while(nextIndex < this.length) {
yield this[nextIndex];
nextIndex++;
}
}
}
var myAssociativeArray = new AssociativeArray();
myAssociativeArray.push("1st", "Bamieh");
myAssociativeArray.push("2nd", "value");
myAssociativeArray.push("3nd", "anotherValue");
console.log('myAssociativeArray::', myAssociativeArray);
console.log('myAssociativeArray.length::', myAssociativeArray.length);
for (let key of myAssociativeArray) {
console.log('key::', key);
}
в основном вы переопределяете Map
или Set
, которые поддерживаются в es6. его хорошая практика - не менее.