As others have commented it's not entirely clear what you're asking here. This code sort of works if you fix the line var Repeaters =[];
I think the confusion is arising because we create Repeaters as an array, but then I think you must be calling collectRepeaterValues with strings for rep_id and cat_id (e.g. 'ID_1' and 'animals') to get the output you are showing. It should be called with numbers if you want to create arrays. You can't access an array element with a string.
If you call with strings JavaScript is going to create object properties on the array when you do Repeaters[rep_id] = Repeaters[rep_id] || []
. That is to say, if we execute the statement Repeaters['ID_1'] = []
in JavaScript it's not doing array assignment even if Repeaters is an array. It will create an object property called ID_1 and makes its value the empty array.
The snippets below show calling the (corrected) object with numbers and with strings and the results.
As an aside, the if statement in collectRepeaterValues is not working.
Now we're back on what the question really is. Do you want arrays, which have to be indexed by numbers of course, or do you want objects with string properties?
// CALLING WITH STRINGS
var RepeaterClass = {
Repeaters: [], // Fixed so it's an object property
collectRepeaterValues: function (rep_id, cat_id, element_id) {
this.Repeaters[rep_id] = this.Repeaters[rep_id] || [];
this.Repeaters[rep_id][cat_id] = this.Repeaters[rep_id][cat_id] || [];
if (-1 === this.Repeaters[rep_id][cat_id].indexOf(element_id)) {
this.Repeaters[rep_id][cat_id].push(element_id);
}
}
}
// What I think you're doing?
RepeaterClass.collectRepeaterValues("ID_1", "category", "dog");
RepeaterClass.collectRepeaterValues("ID_1", "animals", "dog");
RepeaterClass.collectRepeaterValues("ID_1", "animals", "cat");
// At the top level RepeaterClass.Repeaters is an empty array with a 'ID_1' property
// Array length is zero...
console.log(RepeaterClass.Repeaters.length); // 0
// But we have a property ID_1, that is itself an array of zero length with category
// and animals properties that are arrays
console.log(RepeaterClass.Repeaters.ID_1.category[0]); // dog
console.log(RepeaterClass.Repeaters.ID_1.animals[0]); // dog
console.log(RepeaterClass.Repeaters.ID_1.animals[1]); // cat
// Note that this IS the result at the end of the question
// EDIT: You can iterate over the properties with for..in
console.log('Iterating categories on ID_1:');
for (var cat_id in RepeaterClass.Repeaters.ID_1) {
console.log(cat_id);
}
// CALLING WITH NUMBERS
var RepeaterClass = {
Repeaters: [], // Fixed so it's an object property
collectRepeaterValues: function (rep_id, cat_id, element_id) {
this.Repeaters[rep_id] = this.Repeaters[rep_id] || [];
this.Repeaters[rep_id][cat_id] = this.Repeaters[rep_id][cat_id] || [];
if (-1 === this.Repeaters[rep_id][cat_id].indexOf(element_id)) {
this.Repeaters[rep_id][cat_id].push(element_id);
}
}
}
// How this code is meant to be called I think
RepeaterClass.collectRepeaterValues(0, 0, "dog");
RepeaterClass.collectRepeaterValues(0, 1, "dog");
RepeaterClass.collectRepeaterValues(0, 1, "cat");
// At the top level RepeaterClass.Repeaters is now an array structure
console.log(RepeaterClass.Repeaters.length); // 1
console.log(RepeaterClass.Repeaters[0][0][0]); // dog
console.log(RepeaterClass.Repeaters[0][1][0]); // dog
console.log(RepeaterClass.Repeaters[0][1][1]); // cat