I have a simple task of rearranging a couple of Arrays in a JSON, so ractive.js can handle it better. But I got carried away a bit, and the outcome was not particularly satisfactory.
An example of my initial Array:
[{
"_id": 1,
"type": "person",
"Name": "Hans",
"WorksFor": ["3", "4"],
}, {
"_id": 2,
"type": "person",
"Name": "Michael",
"WorksFor": ["3"],
}, {
"_id": 3,
"type": "department",
"Name": "Marketing"
}, {
"_id": 4,
"type": "department",
"Name": "Sales"
}, {
"_id": 5,
"type": "person",
"Name": "Chris",
"WorksFor": [],
}]
So with a given Department I wanted a method in ractive to give me all Persons who work in this Department (with a list of Departments they work for). Something like:
[{
"_id": 1,
"type": "person",
"Name": "Hans",
"WorksFor": ["3", "4"],
"Readable": ["Marketing", "Sales"]
}, {
"_id": 2,
"type": "person",
"Name": "Michael",
"WorksFor": ["3"],
"Readable": ["Sales"]
}]
The function that somehow came to life was similar to this:
function imsorryforthis() {
let output = [];
let tempdocs = this.get('docs'); //as this happens in a ractive method,
//"this.get" is neccesary for binding
for (var i = 0; i < tempdocs.length; i++) {
if (_.contains(tempdocs[i].WorksFor, givenDepartment)) { //I used underscore.js here
let collectedDepartmentData = [];
if (tempdocs[i].WorksFor.length > 0) {
for (var f = 0; f < tempdocs[i].WorksFor.length; f++) {
for (var g = 0; g < tempdocs.length; g++) {
if (tempdocs[i].WorksFor[f] == tempdocs[g]._id) {
let actualDepartmentData = {};
actualDepartmentData = tempdocs[g];
collectedDepartmentData.push(actualDepartmentData);
}
}
}
}
tempdocs[i].Readable = collectedDepartmentData;
output.push(tempdocs[i]);
}
}
return output;
}
I've put it in a Fiddle as well to make it better readable.
Due to the fact that somehow this monstrosity does work (I was astonished myself), it feels like scratching your left ear with your right hand over your head (while being constantly shouted at by a group of desperate mathematicians).
Maybe anybody knows a more presentable and smarter approach (or a way to compile JavaScript so this never sees the light of day again).
Construct a map department_id => department_name
first:
let departments = {};
for (let x of data) {
if (x.type === 'department') {
departments[x._id] = x.Name;
}
}
Then, iterate over Persons and populate Readable
arrays from that map:
for (let x of data) {
if (x.type === 'person') {
x.Readable = x.WorksFor.map(w => departments[w]);
}
}
Finally, extract Persons for the specific Department:
personsInSales = data.filter(x =>
x.type === 'person' && x.WorksFor.includes('3'));