Few notes: - opCall() of AvgWeighted was abstract. - keep in mind that in D classes are CamelCase; - variable names are written like weightSum (but once in a while a underscore doesn't kill). - Be careful because ref arguments are tricky. - There is a line like foreach (r; reputationUser) r = 1; that can be a bug. - foreach (objectID, rating; reputationObject) rating /= weightSum[objectID]; can be another bug. - Use better attribute names in Rating struct, when you need to comment a variable name then it's often a wrong name. - To create structs you can most times use the syntax I've used in the main. - In methods/functions divide your code into paragraphs; - keep your indentations more coherent - I suggest to add contracts and unittests.
Keeping the code tidy helps a lot avoid bugs. The following is surely not perfect, but it's better: struct Rating { uint userID, objectID; double rating; } class Reputation { this() {} this(ref Rating[] ratings, ref double[] reputationUser, ref double[] reputationObject) {} } class AvgWeighted : Reputation { double[] weightSum; this(ref Rating[] ratings, ref double[] reputationUser, ref double[] reputationObject) { weightSum.length = reputationObject.length; foreach (r; ratings) { reputationObject[r.objectID] += r.rating; weightSum[r.objectID] += reputationUser[r.userID]; } foreach (objectID, rating; reputationObject) rating /= weightSum[objectID]; // useless? } void opCall(ref Rating[] ratings, ref double[] reputationUser, ref double[] reputationObject) {} } class AvgArithmetic : AvgWeighted { this(ref Rating[] ratings, ref double[] reputationUser, ref double[] reputationObject) { // foreach (r; reputationUser) r = 1; // bug? reputationUser[] = 1; super(ratings, reputationUser, reputationObject); } void something(ref Rating[] ratings, ref double[] reputationUser, ref double[] reputationObject) { AvgWeighted(ratings, reputationUser, reputationObject); } } void main() { double[] reputationUser; reputationUser.length = 999; double[] reputationObject; reputationObject.length = 1; Rating[] r; foreach (userID; 0 .. reputationUser.length) r ~= Rating(userID, 0, userID % 3); } Bye, bearophile