Chciałbym przeglądać tablicę asocjacyjną jak listę kołową. Najpierw tablica asocjacyjna jest zdefiniowana w następujący sposób:
array = {item1:array(...), item2:array(...), ...}
Kiedy w pierwszym elemencie przeglądam tablicę tego elementu, po dotarciu do ostatniego elementu tej tablicy powinien on przejść do drugiego elementu i przeglądać jego tablicę, i to samo dla ostatniego, który musi wrócić do pierwszego elementu.
Więc inicjalizuję moją tablicę w następujący sposób:
// Build the associative array
Prot.prototype.additem = function(itemName, itemArray)
{
this.array[itemName] = itemArray; // itemArray is an array
}
// Init the currentItem of the associative array to browse (We don't necessarily start at the first)
Prot.prototype.init = function(itemName)
{
this.currentItem = this.array[itemName];
this.currentItemArray = 0;
}
Prot.prototype.next = function()
{
// here I browse the first array of the first key of my associative array
var index = this.currentItem.indexOf(this.currentItemArray);
index = index +1;
this.currentItemArray = this.currentItem[index];
if (index == (this.currentItemArray.length - 1))
{
// when arrives at the last element of the array of the first key I should pass to the second
return false;
}
else {
return true;
}
}
// I add a set interval at the end so no need for a loop
2 odpowiedzi
W JavaScript nie ma czegoś takiego jak tablica asocjacyjna, ale zamiast tego możesz użyć obiektu. Bardzo prosta implementacja definiowania obiektu i odwoływania się do jego właściwości w sposób cykliczny wyglądałaby następująco:
// define the object with 6 properties and assiociated values:
var obj={a:123, b:456, c:789, d:666, e:777, f:888};
function getcirc(obj){
// use a "static variable" inside the function:
if(typeof getcirc.i=="undefined") getcirc.i=0;
var keys=Object.keys(obj), k=keys[getcirc.i++%keys.length];
console.log(k,obj[k]);
}
// call the function repeatedly ...
for (var n=0;n<20;n++) getcirc(obj);
Będziesz potrzebować tablicy, aby wiedzieć, jaka jest „następna” tablica elementów. Dlatego sugerowałbym przechowywanie żądanej kolejności w innej tablicy, mając tylko te nazwy.
Oto możliwa realizacja:
class Prot {
constructor() {
this.itemNames = [];
this.arrays = {};
this.hasData = false;
this.currentIndex = 0;
}
additem(itemName, itemArray) {
if (itemName in this.arrays) throw "duplicate entry";
this.arrays[itemName] = { data: itemArray, index: this.itemNames.length };
this.itemNames.push(itemName); // keep the order
if (itemArray.length) this.hasData = true;
}
init(itemName) {
this.currentItem = this.arrays[itemName];
this.currentIndex = 0;
}
next() {
if (!this.hasData) return;
if (!this.currentItem) this.currentItem = this.arrays[this.itemNames[0]];
var data = this.currentItem.data[this.currentIndex++];
while (this.currentIndex >= this.currentItem.data.length) {
this.currentItem = this.arrays[this.itemNames[(this.currentItem.index+1) % this.itemNames.length]];
this.currentIndex = 0;
}
return data;
}
}
// demo
let obj = new Prot;
// add the arrays:
obj.additem("a", [1, 2, 3]);
obj.additem("b", [4, 5]);
obj.additem("c", [6, 7, 8, 9]);
obj.additem("d", [0]);
// Start at "b":
obj.init("b");
// iterate from there...
for (let i = 0; i < 12; i++) {
console.log(obj.next());
}
Map
, a nie tablice asocjacyjne. Pokaż poprawną składnię i semantykę, w przeciwnym razie nie jest jasne, czego potrzebujesz. Dziękuję.itmeName
powinna wynosićitemName